适配器模式是一种“接口隔离”模式。
什么是“接口隔离”模式:
在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接(且稳定)的接口来隔离本来互相紧密关联的接口是一种常用的解决方案
什么是适配器
简单来说适配器就是一种接口转换工具,比如现实生活中的电源适配器,HMDI转VGA接口等。
适配器模式产生的动机:
在项目,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中使用,但是新的环境中要求的接口和现存的对象不一致。推翻现有的实现,重新按照新的接口规范进行重构显然会浪费很多时间和精力。适配器模式就是为了既能利用现有对象的良好实现,又能满足新的环境所要求的的接口。
适配器模式定义:
将一个类的接口转换成客户希望的另一个接口,Adaptor模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 《设计模式》GOF
代码示例:
现存的老的类:
//遗留接口(老接口)
class IAdaptee{
public:
virtual void foo(int data)=0;
virtual int bar()=0;
};
//遗留类型
class OldClass: public IAdaptee{
//....
};
新环境中要求的接口
//目标接口(新接口)
class ITarget{
public:
virtual void process()=0; // 比如,对于新的process()接口,老接口中的fee()和bar()方法都不满足要求,但是二者通过某种调用关系,或者添加删除一些逻辑,就能满足要求。
};
使用adaptor模式进行转换:
//对象适配器
class Adapter: public ITarget{ //继承
protected:
IAdaptee* pAdaptee;//组合, 组合优于继承。---对象适配器
public:
Adapter(IAdaptee* pAdaptee){
this->pAdaptee=pAdaptee;
}
virtual void process(){
int data=pAdaptee->bar();
pAdaptee->foo(data);
}
};
//类适配器
class Adapter: public ITarget,
protected OldClass{ //多继承, 不推荐。
}
客户程序
int main(){
IAdaptee* pAdaptee=new OldClass();
ITarget* pTarget=new Adapter(pAdaptee);
pTarget->process();
}
要点总结:
- Adaptor模式主要应用于“希望复用一些现存的类,但是接口又与服用环境要求不一致的情况”, 在遗留代码服用, 类库迁移等方面非常有用。
- GOF定义了两种Adaptor模式的实现结构: 对象适配器和类适配器。类适配器采用“多继承”的方式实现,会出现很多问题,一般不推荐使用。对象适配器使用“对象组合”的方式,更符合松耦合精神。
- Adaptor模式可以实现的非常灵活,不用像GOF定义的那样严格。比如,可以将Adaptor模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。