Java设计模式06:常用设计模式之适配器模式(结构型模式)
1. Java之适配器模式(Adapter Pattern)
(1)概述:
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类,可以在一起工作。
(2)应用场景:
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
• 已经存在的类的接口不符合我们的需求;
• 创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;
• 在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类。
(3)模式中的角色
• 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
• 需要适配的类(Adaptee):需要适配的类或适配者类。
• 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
(4)模式解读
注:在GoF的设计模式中,对适配器模式讲了两种类型,类适配器模式 和 对象适配器模式。
2. 类适配器模式的实现:
类适配器模式就是主要用于,单一的为某个类而实现适配的这样一种模式,为什么说只为某个类去实现,一会提到,我们先展示这种类适配模式的代码实现。
(1)类适配器模式的UML图:
其中:
Target
----- 定义Client使用的与特定领域相关的接口。
Client
----- 与符合Target接口的对象协同。
Adaptee
----- 定义一个已经存在的接口,这个接口需要适配。
Adapter
----- 对Adaptee的接口与Target接口进行适配
(2)代码实现:
1 // 已存在的、具有特殊功能、但不符合我们既有的标准接口的类 2 class Adaptee { 3 public void specificRequest() { 4 System.out.println("被适配类具有 特殊功能..."); 5 } 6 } 7 8 9 // 目标接口,或称为标准接口 10 interface Target { 11 public void request(); 12 } 13 14 // 具体目标类,只提供普通功能 15 class ConcreteTarget implements Target { 16 public void request() { 17 System.out.println("普通类 具有 普通功能..."); 18 } 19 } 20 21 22 // 适配器类,继承了被适配类,同时实现标准接口 23 class Adapter extends Adaptee implements Target{ 24 public void request() { 25 super.specificRequest(); 26 } 27 } 28 29 30 // 测试类 31 public class Client { 32 public static void main(String[] args) { 33 // 使用普通功能类 34 Target concreteTarget = new ConcreteTarget(); 35 concreteTarget.request(); 36 37 // 使用特殊功能类,即适配类 38 Target adapter = new Adapter(); 39 adapter.request(); 40 } 41 }
测试结果:
普通类 具有 普通功能...
被适配类 具有 特殊功能...
上面这种实现的适配器称为类适配器,因为 Adapter 类既继承了 Adaptee (被适配类),也实现了 Target 接口(因为 Java 不支持多继承,所以这样来实现),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。
3. 对象适配器
另外一种适配器模式是对象适配器,它不是使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式。对象的适配器模式,把"源"作为一个构造参数传入适配器,然后执行接口所要求的方法。这种适配模式可以为多个源进行适配。弥补了类适配模式的不足。
(1)对象适配器UML图:
(2)代码实现:
1 // 适配器类,直接关联被适配类,同时实现标准接口 2 class Adapter implements Target{ 3 // 直接关联被适配类 4 private Adaptee adaptee; 5 6 // 可以通过构造函数传入具体需要适配的被适配类对象 7 public Adapter (Adaptee adaptee) { 8 this.adaptee = adaptee; 9 } 10 11 public void request() { 12 // 这里是使用委托的方式完成特殊功能 13 this.adaptee.specificRequest(); 14 } 15 } 16 17 18 // 测试类 19 public class Client { 20 public static void main(String[] args) { 21 // 使用普通功能类 22 Target concreteTarget = new ConcreteTarget(); 23 concreteTarget.request(); 24 25 // 使用特殊功能类,即适配类, 26 // 需要先创建一个被适配类的对象作为参数 27 Target adapter = new Adapter(new Adaptee()); 28 adapter.request(); 29 } 30 }
4. 小结:
现在来对2种适配模式做个分析:
(1)类的适配模式用于单一源的适配,由于它的源的单一话,代码实现不用写选择逻辑,很清晰;而对象的适配模式则可用于多源的适配,弥补了类适配模式的不足,使得原本用类适配模式需要写很多适配器的情况不复存在,弱点是,由于源的数目可以较多,所以具体的实现条件选择分支比较多,不太清晰。
(2)适配器模式主要用于几种情况:
• 系统需要使用现有的类,但现有的类不完全符合需要。
• 讲彼此没有太大关联的类引进来一起完成某项工作(指对象适配)。