Adapter
定义 :
适配器模式,把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
通过创建适配器进行接口转换,让不兼容的接口变得兼容。
两种实现方式 :
一, 类适配器
二, 对象适配器
类适配器的结构和角色
目标角色(Target) : 此角色是客户端所期待的接口。(由于这是类适配器,所以这里只能是接口而不能是类,因为Java只支持单继承)
源角色(Adaptee) : 此角色是需要适配的类。
适配器角色(Adapter) : 适配器类是模式的核心。适配器把源接口转换成目标接口。这里必须是类。
package ds.adapter; public interface Target { public void operation(); }
package ds.adapter; public class Adaptee { public void operation() { System.out.println("this is Adaptee's operation method"); } }
package ds.adapter; public class Adapter extends Adaptee implements Target{ //采用继承, Adapter继承了Adaptee类的operation方法。所以可以省略实现Target类的opertaion方法 这是类适配器相对对象适配器的一个优点。 }
package ds.adapter; public class Client { public static void main(String[] args) { //客户端需要调用execute方法,但是execute方法需要一个Target的参数。而现有类 Adaptee 并不实现 Target接口。所以不能使用。 // execute(new Adaptee()); Compile error //采用 Adapter 适配器类, 用 Adapter 实现 Target 接口。并且继承 Adaptee 类。 execute(new Adapter()); } public static void execute(Target target) { // 这里实际调用的是 Adaptee 的 operation 方法, 因为Adapter没有重写Adaptee类的operation方法 target.operation(); } }
对象适配器的结构和角色 :
目标角色(Target) : 此角色是客户端所期待的接口。(可以是类)
源角色(Adaptee) : 此角色是需要适配的接口, 这里可以是接口,所以此接口的子类都可以充当被适配者角色。
适配器角色(Adapter) : 适配器类是模式的核心。适配器把源接口转换成目标接口。这里必须是类。
package ds.adapter; public interface Target { public void operation(); }
package ds.adapter; public class Adaptee { public void operation() { System.out.println("this is Adaptee's operation method"); } }
package ds.adapter; public class SubAdaptee extends Adaptee{ public void operation() { System.out.println("this is SubAdaptee's operation method"); } }
package ds.adapter; public class Adapter implements Target{ // 这里 Adaptee 可以是接口或抽象类 private Adaptee adaptee; // 此适配器适用 Adaptee 等级结构的类, 而不需每一个子类都要写一个适配器 public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } //这里必须实现 Target 接口的 operation 方法 @Override public void operation() { adaptee.operation(); } }
package ds.adapter; public class Client { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); execute(new Adapter(adaptee)); // 采用对象适配器,适配器类和被适配器类是组合的关系。可以在运行时决定具体的类型。 类适配器采用继承则必须在编译期决定被适配类 adaptee = new SubAdaptee(); // Adaptee类的子类 也可以使用 适配器 execute(new Adapter(adaptee)); } public static void execute(Target target) { target.operation(); } }
类适配器和对象适配器 :
如果只有一个类需要适配的情况,可以使用类适配器,这样适配器类可以不需要重新实现被适配器类。
当被适配类有多个时,且在同一类等级结构下,使用对象适配器更灵活。这是"组合优于继承"的一个体现。而使用类适配器的话就必须为每一个被适配类写一个适配器类,或者更改适配源,这是不可取的。
应用 :
系统需要使用现有类,而此类的接口不符合系统的需要。
IO,字符流转字节流。
一个技巧 :
目标接口可以省略,此时,目标接口和源接口实际上是相同的。当我们不想实现一个超大接口时,我们可以用适配器实现这个接口,然后在适配器里实现客户端不必实现的方法。这里的适配器可以是一个抽象类。