适配器模式
动机
适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作。这就是适配器模式的模式动机。
在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器和类适配器两种,在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承(或实现)关系。在实际开发中,对象适配器的使用频率更高,对象适配器模式结构如图所示:
在对象适配器模式结构图中包含如下几个角色: Target(目标抽象类)︰目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。
Adapter(适配器类)︰适配器可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配,适配器类是适配器模式的核心,在对象适配器中,它通过继承Target并关联一个Adaptee对象使二者产生联系。
Adaptee(适配者类)∶适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码。
场景
比如我们实现了一个新版的功能类Adaptee
其中功能比之前更新,但方法名不同,接口名也不同。
我们可以使用一个适配器Adapter
来转接这个接口。即使用之前的类,之前的方法名,但调用了新的功能。
两种实现
对象
适配器中构建适配者,通过适配者调用方法
class Target {//目标
public:
virtual void request() {
cout << "Target::request" << endl;
}
};
class Adaptee {//适配者
public:
virtual void specficRequest() {
cout << "Adaptee::specficRequest" << endl;
}
};
class Adapter :public Target {
private:
Adaptee* adaptee;
public:
Adapter():adaptee(new Adaptee){}
~Adapter() { delete adaptee; }
virtual void request() {
cout << "Adapter::request(Adaptee::specficRequest)" << endl;
adaptee->specficRequest();
}
};
int main() {
unique_ptr< Target> tg(new Adapter);
tg->request();
}
继承
将适配者也继承过来,直接使用适配者方法。
class Adapter :public Target,private Adaptee {
public:
virtual void request() {
Adaptee::specficRequest();
}
};