适配器模式的作用:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
适配器模式主要包括三种:类适配器模式,对象适配器模式,接口适配器模式
1.类适配器模式
类的适配器模式把适配的类的API转换成为目标类的API。
在上图中可以看出,Adaptee类并没有sampleOperation2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,提供一个中间环节,即类Adapter,把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是继承关系,这决定了这个适配器模式是类的:
模式所涉及的角色有:
● 目标(Target)角色:这就是所期待得到的接口。注意:由于这里讨论的是类适配器模式,因此目标不可以是类。
● 源(Adapee)角色:现在需要适配的接口。
● 适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。
public interface Target {
public void sampleOperation1();
public void sampleOperation2();
}
public class Adaptee {
public void sampleOperation1() {
System.out.println("sampleOperation1");
}
}
public class Adapter extends Adaptee implements Target {
public void sampleOperation2() {
System.out.println("sampleOperation2");
}
}
public class Test {
public static void main(String[] args) {
Target target = new Adapter();
target.sampleOperation1();
target.sampleOperation2();
}
}
sampleOperation1
sampleOperation2
Process finished with exit code 0
2.对象适配器模式
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是 使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类,其实就是组合方式。从上图可以看出,Adaptee类并没有sampleOperation2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供
一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。
Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。
public interface Target { public void sampleOperation1(); public void sampleOperation2(); }
public class Adaptee { public void sampleOperation1() { System.out.println("sampleOperation1"); } }
public class Adapter implements Target { Adaptee adaptee; Adapter (Adaptee adaptee) { super(); this.adaptee = adaptee; } public void sampleOperation1() { this.adaptee.sampleOperation1(); } //新方法 public void sampleOperation2() { System.out.println("sampleOperation2"); } }
public class Test { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target target = new Adapter(adaptee); target.sampleOperation1(); target.sampleOperation2(); } }
sampleOperation1 sampleOperation2 Process finished with exit code 0
3.接口适配器模式接口适配器模式我看到过两种说法,以下都列举出来
1)在客户端接口的实现方法和现有类相同但是方法名不同时,适配器继承现有类并实现客户端接口,其实这种方式看上去很像类的适配器模式
//客户提供的的接口 public interface Target { public void sampleOperation1(); public void sampleOperation2(); }
//现有类 public class Adaptee { public void sampleOper1() { System.out.println("sampleOperation1"); } public void sampleOper2() { System.out.println("sampleOperation1"); } }
//适配器类 public class Adapter extends Adaptee implements Target { public void sampleOperation1() { sampleOper1(); } public void sampleOperation2() { sampleOper2(); } }
public class Test { public static void main(String[] args) { Target target = new Adapter(); target.sampleOperation1(); target.sampleOperation2(); } }
sampleOperation1 sampleOperation1 Process finished with exit code 0
2)借助一个抽象类,该抽象类实现了接口的所有方法,我们再自己写类来继承这个抽象类根据需求重写方法public interface Target { public void sampleOperation1(); public void sampleOperation2(); }
public abstract class Adapter implements Target { public void sampleOperation1() {} public void sampleOperation2() {} }
public class sample1 extends Adapter { @Override public void sampleOperation1() { System.out.println("sampleOperation1"); } }
public class sample2 extends Adapter { @Override public void sampleOperation2() { System.out.println("sampleOperation2"); } }
public class Test { public static void main(String[] args) { sample1 s1 = new sample1(); sample2 s2 = new sample2(); s1.sampleOperation1(); s2.sampleOperation2(); } }
sampleOperation1 sampleOperation2 Process finished with exit code 0
总结:类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
对象的适配器模式:当希望在新类拥有另一个类的一些方法时,可以让新类持有原类的一个实例,在新类的方法中,调用实例的方法就行。
接口的适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类实现所有方法,我们写别的类的时候,继承抽象类即可。