常用设计模式之适配器模式

来源:互联网 发布:后现代主义文化网络 编辑:程序博客网 时间:2024/06/07 08:18

1.问题描述

客户要求开发日志管理功能。第一版日志管理操作实现了读写文件,但客户又想对日志进行增删改查功能,因此,根据客户要求开发第二版。但实现第二版日志操作的接口后,还想增加数据库存储的功能。

问题在于,现在的业务都是使用第二版的接口,对于新加入的保存日志到数据库中;但是对于已有的实现方式,它的操作接口和第二版不一样,因而导致现在客户端无法以同样的方式来直接使用第一版的实现,如图所示:


图1 问题描述

2.模式引入

将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

3.应用适配器模式来解决问题的思路

上述问题的根源在于接口的不兼容,功能是基本实现了,只要想办法让两边的接口匹配起来,就可以复用第一版的功能了。

按照适配器模式的实现方式,可以定义一个类来实现第二版的接口,然后在内部实现的时候,转调第一版已经实现了的功能,通过对象组合的方式,既复用了第一版已有的功能,同时又在接口上满足了第二版调用的要求。

4.适配器模式实例


图2 适配器模式实例类图

  • Client:客户端,调用自己需要的接口Target;
  • Target:定义客户端需要的跟特定功能相关的接口;
  • Adaptee:已经存在的接口,通过能满足客户端的功能要求,但是接口与客户端要求的特定功能接口不一致,需要被适配;
  • Adapter:适配器,把Adaptee适配成为Client需要的Target.



图3 适配器模式实例时序图

5.适配器模式实例代码

/** *  *  * description: 已经存在的接口,这个接口需要适配<br/> *  * author: fanruifa <br/> *  * date: 2013-5-21 <br/> *  */public class Adaptee {public void specificRequest() {System.out.println("Adaptee实现的请求");}}
/** *  *  * description: 定义客户端使用的接口,与特定功能相关<br/> *  * author: fanruifa <br/> *  * date: 2013-5-21 <br/> *  */public interface Target {void request();}
/** *  *  * description: 适配器<br/> *  * author: fanruifa <br/> *  * date: 2013-5-21 <br/> *  */public class Adapter implements Target {private Adaptee adaptee; // 需要适配的对象public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {// 转调实现方法,进行适配adaptee.specificRequest();}}
/** *  *  * description: 使用适配器客户端<br/> *  * author: fanruifa <br/> *  * date: 2013-5-21 <br/> *  */public class AdapterClient {public static void main(String[] args) {Adaptee adaptee = new Adaptee();Target target = new Adapter(adaptee);target.request();}}
6.适配器模式本质

转换匹配,复用功能。

7.何时选用适配器模式

  • 如果你想使用一个已经存在的类,但是它的接口不符合你的需求,这种情况可以使用适配器模式,来把已有的实现转换成你需要的接口;
  • 如果你想创建一个可以复用的类,这个类可能和一些不兼容的类一起工作,这种情况可以使用适配器模式,到时候需要什么就适配什么;
  • 如果你想使用一些已经存在的子类,但是不可能对每一个子类都进行适配,这种情况可以先用对象适配器,直接适配这些子类的父类就可以了。