Adapter适配器模式

Adapter模式用来将一个类的接口转换为另一个更合适的接口。意思就是说,当你调用A接口时,发现A接口虽然功能上差不多满足需求,但是仍有部分功能没有、或者接口定义或返回值不能满足当前需求,你就需要一个适配器(Adapter),将A接口转换为Adapter接口。
Adapter模式有时候也被称为Wrapper模式,两者思路上是相同的,唯一的不同是看待问题的角度不同。Wrapper是包装的意思,Adapter是适配的意思。
Adpter模式分为两种,一种是对象适配器,一种是类适配器。一般比较常用的是对象适配器。

对象适配器:

如下图,被适配的类是Adaptee,它有一个方法methodB,但是不适合我们的客户端Client,所以就需要一个适配器Adaptor。Adaptor为客户提供满足客户需求的methodA,在methodA中再调用Adaptee对象的methodB方法。但是它的作用远远不止这些,最简单的模型大概就是这样了。

基于该类图的代码如下,首先是老的不适配的类:

1
2
3
4
5
6
7
public class Adaptee {

public String method1(){
return "original";
}

}

我们期望的接口如下:

1
2
3
public interface Adapter {
int methodA();
}

对象适配器如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ObjectAdapter implements Adapter {


private Adaptee adaptee;

ObjectAdapter(Adaptee adaptee){
this.adaptee = adaptee;
}

@Override
public int methodA() {
if("original".equals(adaptee.method1())){
return 1;
}else{
return 0;
}
}

}

一个典型的例子是jdom中的DOMAdapter,DOMAdapter接口定义了各种DOM操作应该适配的接口,然后各种适配器(如XML4JDOMAdapter、JAXPDOMAdapter)实现了DOMAdapter接口,完成了把各种DOM模型转换成jdom中需要的Document模型。
一个更好的例子是Android SDK中的Adpater接口,Adapter接口定义了View视图显示需要的数据接口,针对不同的数据源,你可以写不同的Adapter来实现,常见的有XMLAdapter、ArrayAdapter等等。关于这个例子有一篇文章介绍的很详细,可以参考这篇文章《Adapter软件设计模式在Android中的应用

类适配器:

类适配器一般是使用多态接口来实现,Adapter通过同时实现两个接口(期望的接口和原来不适配的接口)或者继承的方式来完成。注意Java不支持多重继承,只能通过实现期望的接口并且继承原来的类来实现Adapter。类适配器的类图如下:

老的不适配的类和期望的接口与上面的类似,类适配器如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class ClassAdapter extends Adaptee implements Adapter {

@Override
public int methodA() {
if("original".equals(this.method1())){
return 1;
}else{
return 0;
}
}

}

其实,这仅仅只是面向对象中的多态而已,不是吗?确实,很多设计模式无非就是利用了面向对象中的继承、封装、多态等特性而已,这才是面向对象的本质。
适配器模式在现实生活中的例子十分类似电源适配器,笔记本需要指定规格的电源,但生活中用的电源标准不一样,电源适配器很好的适配了各种类型的电源,使得你的笔记本到处可用。