意图
- 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
适用性
- 你想使用一个已经存在的类,而它的接口不符合你的需求
- 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(接口可能不一定兼容的类)协同工作
- (仅适用对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口,对象适配器可以适配它的父类接口。
结构
- 类适配器
- 对象适配器
参与者
- Target
- 定义Client使用的与特定领域相关的接口
- Client
- 与符合Target接口相关的对象协同
- Adaptee
- 定义一个已经存在的接口,这个接口需要适配
- Adapter
- 对Adaptee的接口与Target接口进行适配
协作
- Client在Adapter实例上调用一些操作。接着适配器调用Adaptee的操作实现这个请求
效果
- 类适配器
- 用一个具体的Adapter类对Adaptee和Target进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作
- 使得Adapter可以重定义Adaptee的部分行为。
- 仅仅引入了一个对象,并不需要额外的指针以间接得到adaptee
- 对象适配器
- 允许一个Adapter与多个Adaptee——即Adaptee本身以及它的所有子类同时工作
- 使得重定义Adaptee的行为变得困难。
- 使用该模式时需要考虑的其他因素:
- Adapter的匹配程度
- 可插入的Adapter
- 使用双向适配器提供透明操作(双向适配器)
实现
- 使用C++实现适配类:在使用C++实现适配器类时,Adapter类应该采用公共方式继承Target类,并且用私有方式继承Adaptee类。
- 可插入的适配器:
- 使用抽象操作
- 使用代理对象
- 参数化的适配器
代码示例
对象适配模式
- Client
class Client
{
public Client()
{
Target target = new Adapter();
target.Request();
}
}
- Target Adaptee Adapter
class Target
{
public virtual void Request()
{
Console.WriteLine(" target call request");
}
}
class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine(" Adaptee call SpecificRequest");
}
}
class Adapter:Target
{
private Adaptee adaptee = new Adaptee();
public Adapter()
{
}
public override void Request()
{
adaptee.SpecificRequest();
}
}
- 还有一个类适配模式,由于C#不支持多继承,暂不列出来。后期用C++实现。
相关模式
模式Bridge的结构与对象适配器类似,但是Bridge模式的出发点不同:Bridge的目的时将接口部分与实现部分分离,从而对它们可以较容易也相对独立于加以改变。而Adapter则意味着改变一个已有对象的接口
Decorator 模式增强了其他对象的功能而同时又不改变它的接口。因此decorator对应程序的透明性比适配器好,结果是decorator支持递归组合,而纯粹使用适配器不可能实现这一点。
Proxy模式在不改变接口的条件下,为另一个对象定义了一个代理。