1、意图
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2、适用性
以下情况使用Adapter模式
(1)你想使用一个已经存在的类,而它的接口不符合你的需求
(2)你想创建一个可以复用的类,该类可以与其它不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作
(3)你想使用一些已经存在 的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可参适配它的父类接口,这种情况仅适用于对象Adapter
3、结构
分为类适配器和对象适配器。
类适配器使用多重继承对一个接口与另一个接口进行匹配。
对象适配器依赖于对象组合。
对象适配器的代码如下
#include <iostream>
#include <string>
using namespace std;
class Target
{
public:
virtual string operation() = 0;
};
class Adaptee
{
public:
string method1() {return "Adapter";}
string method2() {return " pattern";}
};
class Adapter : public Target
{
Adaptee &adaptee;
public:
Adapter(Adaptee &a) : adaptee(a) {}
string operation()
{
return adaptee.method1() + adaptee.method2();
}
};
void f(Target &t)
{
cout << t.operation() << endl;
}
int main()
{
Adaptee adaptee;
Adapter adapter(adaptee);
f(adapter);
return 0;
}
4、参与者
(1)Target:定义Client使用的与特定领域相关的接口
(2)Client:与符合Target接口的对象协同
(3)Adaptee:定义一个已经存在的接口,这个接口需要适配
(4)Adapter:对Adaptee的接口与Target接口进行适配
5、协作
Client在Adapter实例上调用一些操作。接着适配器调用Adaptee的操作实现这个请求。
6、效果
类适配器和对象适配器有不同的权衡。
类适配器原则
(1)用一个具体的Adapter类对Adaptee和Target进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作。
(2)使得Adaqter可以重新定义Adaptee的部分行为,因为Adapter是Adaptee的一个子类
(3)仅仅引入了一个对象,并不需要额外的指针以间接得到adaptee.
对象适配器原则
(1)允许一个Adapter与多个Adaptee——即Adaptee本身以及它的所有子类同时工作。Adapter也可以一次给所有的Adaptee添加功能。
(2)使得重定义Adaptee的行为比较困难。这就需要生成Adaptee的子类并且使得Adapter引用这个子类而不是引用Adaptee本身。
7、相关模式
Bridge模式的结构与对象适配器类似,但是Bridge模式的出发点不同:Bridge目的是将接口部分与实现部分分离,从而对它们可以较为容易也相对独立的加以改变。而Adapter则意味着改变一个书友对象的接口
Decorator模式增强了其他对象 的功能而同时不改变它的接口。因些Decorator对应用程序的透明性比适配器要好。结果是decorator支持递归组合,而纯粹使用适配器是不可能实现这一点的。
Proxy模式在不改变它的接口的条件下,为另一个对象定义了一个代理。