声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客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();
}
}