读《研磨设计方式》-代码笔记-适配器模式-Adapter
读《研磨设计模式》-代码笔记-适配器模式-Adapter
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/
package design.pattern; /* * 适配器模式解决的主要问题是,现有的方法接口与客户要求的方法接口不一致 * 可以这样想,我们要写这样一个类(Adapter): * 1.这个类要符合客户的要求 ---> 那显然要implements客户要求的接口 * 2.这些接口的实现是调用已有的类 ---> 有两种方法可获得已有的类的方法: * a.组合。对应“对象适配器” * b.继承。对应“类适配器” * * 书上讲了一个新旧版日志操作的例子(旧版日志是存储在文件里,新版是存储在数据库里) * 书上说“新旧版日志共存”,但我觉得主要解决的问题不是共存(书上也不关注新版日志操作如何实现), * 而是应该强调如何“用新版日志的接口方法去调用旧版” * 书上新版日志操作的一个方法,正是调用了旧版的方法来实现,而新版的实现需自行处理,不在讨论范围内: public void updateLog(LoginModel lm){ List<LogModel> list = adaptee.readLogFile(); //旧版的方法,文件操作 for(int i=0;i<list.size();i++){ if(list.get(i).getLogId().equals(lm.getLogId())){ list.set(i, lm); break; } } adaptee.writeLogFile(list); } 书上最后作了一个扩展:双向适配器,也是很有实际意义的。还是以日志操作为例,要求: 1、主要使用旧版接口,但使用旧版接口时也希望能调用新版接口 2、新版接口能兼容旧版接口——这是前面的例子 我的理解其实就是说适配器为这两个需求提供两个“视图”或者说两套接口 视图1: 1.正常使用旧接口的方法(例如这个方法叫method()) 2.调用适配器的方法,从而实现“也能调用新接口”: new Adapter().method(); 视图2: 1.正常使用新接口的方法(例如这个方法叫method2()) 2.调用适配器的方法,从而实现“也兼容旧接口”: new Adapter().method2(); 对于适配器来说,这其实有点分裂:旧版方法method()里面的实现代码其实是新版的实现代码,method2()里面的实现代码其实是旧版的实现代码 */ //客户要求的接口 interface Target { void request(); } //现有的接口或方法。与客户要求不一致。这个“不一致”可能是多样的,不局限于“方法名不一致” //这个Adaptee也可以是实现现有的某个接口 class Adaptee { public void specificRequest() { System.out.println("specificRequest in adaptee."); } } //对象适配器 class ObjectAdapter implements Target { //如果Adaptee是implements某个接口,那应该写成: //private IAdaptee adaptee; private Adaptee adaptee; public ObjectAdapter(Adaptee adaptee) { this.adaptee = adaptee; } //调用旧的方法 public void request() { adaptee.specificRequest(); } } //类适配器 class ClassAdapter extends Adaptee implements Target { public void request() { super.specificRequest(); } } //扩展:双向适配器 interface IOldAdaptee { public void method(); } interface INewAdaptee { public void method2(); } class TwoWayAdapter implements IOldAdaptee, INewAdaptee { private IOldAdaptee oldAdaptee; private INewAdaptee newAdaptee; public void method() { newAdaptee.method2(); } public void method2() { oldAdaptee.method(); } } class OldAdaptee implements IOldAdaptee { public void method() {} } class NewAdaptee implements INewAdaptee { public void method2() {} } class OldClient { public void test(){ IOldAdaptee adaptee = new OldAdaptee(); adaptee.method(); //现在客户想通过旧接口调用新版的方法,那就要有一个适配器 IOldAdaptee adapter = new TwoWayAdapter(); //注意这里adapter在类型是IOldAdaptee,也就是提供的是旧版的”视图“ adapter.method(); //适配器里面调用的是新版的方法 } } class NewClient { public void test(){ INewAdaptee adaptee = new NewAdaptee(); adaptee.method2(); //现在客户想通过新接口调用旧版的方法,那就要有一个适配器 //INewAdaptee adapter = new TwoWayAdapter(); adaptee = new TwoWayAdapter(); adaptee.method2(); //适配器里面调用的是旧版的方法 } } public class AdapterPattern { public static void main(String[] args) { Adaptee adaptee = new Adaptee(); Target adapter = new ObjectAdapter(adaptee); adapter.request(); Target adapter2 = new ClassAdapter(); adapter2.request(); } }