适配器模式的官方定义是:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
举例说明:很多的插座都是两孔的,但是你的台灯的电源线却有三个脚,这样你无法直接将台灯直接使用,要想三脚的电源线插到两孔的插座上你需要买一个(三脚-两孔)的转换器来将它们适配起来,而这个转换器我们称之为适配器。
适配器模式分为3类:类的适配器模式、对象的适配器模式、接口的适配器模式。
1.类的适配器模式:
你有一个源类,他有一个method1()方法,如下
public class source{
public void method1(){
System.out.println("this is method1");
}
}
但是你的客户期望的接口并不是这个源类这样的,他不仅仅需要有method1方法还需要有method2方法。如下:
public interface targrt{
public void method1();
public void method2();
}
此时,要想满足目标接口你需要创建一个适配器,它既有source的method1方法还有类interface的method方法,如下:
class adapter extends source implements targrt{
/*
* method1方法可以直接从source继承过来
* 自己实现接口中的method2方法
*/
@Override
public void method2() {
System.out.println("this is method2");
}
}
但是这样做是有一个大问题就是当Source类有两个时,由于Java时单继承的,无法通过类适配器模式来完成。如:
public class source1{
public void method3(){
System.out.println("this is method3");
}
}
2.对象适配器模式
对象适配器模式跟类适配其模式相比仅仅是改变了Adapter类。如下:
class adapter implements targrt{
private Source source;
private Source1 source1;
public Adapter(Source source,Source1 source1){
this.source = source;
this.source1 = souce1;
}
public void method1(){
this.source.method1();
}
public void method3(){
this.source1.method3();
}
/*
* 自己实现接口中的method2方法
*/
@Override
public void method2() {
System.out.println("this is method2");
}
}
对象适配器模式是将源方法的实现通过持有一个源实例的形式,这样当有多个source类时可以通过持有多个实例来实现,解决了类适配其模式的问题。
3.缺省适配模式
缺省适配(Default Adapter)模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。
很多时候我们的写的一个类需要继承一个目标接口,但是这个目标接口有很多方法我们用不上,我们想只实现其中想要的方法时可以使用缺省适配器模式。首先定义一个抽象类来继承目标接口,然后用自己的类去继承这个抽象类的方式实现目标接口。如下:
/*
* 目标接口,其中我们只想要method1方法
*/
public interface Target{
public void method1();
public void method2();
}
public abstract class Adapter implements Target{
public void method1(){}
public void method2(){}
}
我们写的类(只去实现method1方法):
public class MyClass extends Adapter{
public void method1(){
System.out.println("this is method1");
}
}
最后的Test类:
public class Test {
public static void main(String[] args) {
Target target = new MyClass();
}
}
总结:
类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个类,持有原类的一个实例,在类的方法中,调用实例的方法就行。
缺省适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类,实现所有方法,我们写别的类的时候,继承抽象类即可。
适配器模式的缺点:
过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。