设计理念
将一个类的接口,转换成客户期望的另一接口。适配器让原本接口不兼容的类可以无间合作。
适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作。这就是适配器模式的模式动机。
适配器模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
UML类图
适配器模式有对象适配器和类适配器两种形式的实现结构,但是类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
类适配器
对象适配器
- Target:目标抽象类,客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
- Adapter:适配器类,通过包装一个需要适配的对象,把原接口转换成目标接口。
- Adaptee:适配者类,需要适配的类或适配者类。
- Client:客户类,使用适配器的对象。
实现代码
#include <iostream>
#include "Adapter.h"
#include "Adaptee.h"
#include "Target.h"
using namespace std;
int main(int argc, char *argv[])
{
Adaptee * adaptee = new Adaptee();
Target * tar = new Adapter(adaptee);
tar->request();
return 0;
}
///////////////////////////////////////////////////////////
// Adapter.h
// Implementation of the Class Adapter
///////////////////////////////////////////////////////////
#include "Target.h"
#include "Adaptee.h"
class Adapter : public Target
{
public:
Adapter(Adaptee *adaptee);
virtual ~Adapter();
virtual void request();
private:
Adaptee* m_pAdaptee;
};
///////////////////////////////////////////////////////////
// Adapter.cpp
// Implementation of the Class Adapter
///////////////////////////////////////////////////////////
#include "Adapter.h"
Adapter::Adapter(Adaptee * adaptee){
m_pAdaptee = adaptee;
}
Adapter::~Adapter(){
}
void Adapter::request(){
m_pAdaptee->specificRequest();
}
///////////////////////////////////////////////////////////
// Adaptee.h
// Implementation of the Class Adaptee
///////////////////////////////////////////////////////////
class Adaptee
{
public:
Adaptee();
virtual ~Adaptee();
void specificRequest();
};
总结
适配器模式包含四个角色:目标抽象类定义客户要用的特定领域的接口;适配器类可以调用另一个接口,作为一个转换器,对适配者和抽象目标类进行适配,它是适配器模式的核心;适配者类是被适配的角色,它定义了一个已经存在的接口,这个接口需要适配;在客户类中针对目标抽象类进行编程,调用在目标抽象类中定义的业务方法。
适配器模式的主要优点是将目标类和适配者类解耦,增加了类的透明性和复用性,同时系统的灵活性和扩展性都非常好,更换适配器或者增加新的适配器都非常方便,符合“开闭原则”;类适配器模式的缺点是适配器类在很多编程语言中不能同时适配多个适配者类,对象适配器模式的缺点是很难置换适配者类的方法。
抽象的JDBC接口和各个数据库引擎API之间都需要相应的适配器软件,这就是为各个不同数据库引擎准备的驱动程序。
使用过ADO.NET的开发人员应该都用过DataAdapter,它就是用作DataSet和数据源之间的适配器。DataAdapter通过映射Fill和Update来提供这一适配器。
参考连接
http://www.cnblogs.com/wangjq/archive/2012/07/09/2582485.html
http://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/adapter.html
http://gpp.tkchu.me/