C++设计模式之适配器(Adapter)模式

1. 标准定义
适配器模式标准定义:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2. 分析和说明
适配器模式属于结构型设计模式。适用性:你想使用一个已经存在的类,而它的接口不符合你的需求。你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。(仅适用于对象Adapter )你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配器模式也叫变压器模式,也叫包装器(Wrapper)模式。
当一个类需要另一个类的方法,但是这两个类并兼容。从实现原理上来看.达到这一目的的方法有两种:一种是继承,一种是对象组合。第一种方法中.从一个非一致性的类中派生一个新类,并增加新的方法使派生类与所需接口匹配;第二种方法中.在新类中包含最初的类.并创建方法来解释新类中的调用.这两种方法即人们通常所俗称的类适配器和对象适配器。适配器可以采用类的适配器,也可以采用对象的适配器。
适配器(Adapter)模式结构包括的角色有目标(Target)角色、源(Adaptee)角色和适配器(Adapter)角色。
目标(Target)角色:这就是所期待的接口,定义了客户所期望的操作。目标(Target)角色可以是具体类或抽象类。该角色不可缺少。
源(Adaptee)角色:这是我们原有的产品,也是需要被适配的产品。这是我们原有的产品,也是需要被适配的产品:源(Adaptee)角色可以用接口、抽象类和具体类来实现。该角色不可缺少。
适配器(Adapter)角色:适配器角色是本模式的核心。Adapter对Adaptee接口与Target接口进行适配,适配器把源接口转换成目标接口,在Target目标角色与Adaptee源角色之间提供一种过渡,即把Adaptee源角色所提供的接口转换为Target目标角色所提供的接口。适配器(Adapter)角色必须是具体类。该角色不可缺少。
3.适配器模式特点:
适配器模式主要解决的问题就是我们要调用的接口类型,无法满足我们新系统的使用需求,这时候,我们需要将旧系统的接口,通过适配器进行转配,达到支持新接口调用的目的。对于这样的要求,我们通过适配器就可以完成,当然如果有多个接口需要转配,那么我们就需要为每一个接口提供一个适配器去完成转换的工作。具体的调用过程,我们可以进行相应的封装。达到比较通用的方式去调用适配器,完成适配服务。
a.Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
b.Adapter模式有对象适配器和类适配器两种形式的实现结构,但是类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。在Adapter模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接口)。在C++中的public继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过private继承获得实现继承的效果(private继承后,父类中的接口都变为private,当然只能是实现继承了。),通过纯抽象基类模拟接口继承的效果,但是在C++中pure virtual function也可以提供默认实现,因此这是不纯正的接口继承,但是在Java中我们可以interface来获得真正的接口继承了。
4.适用场景:
系统需要使用现有的类,而此类的接口不符合系统的需要。
注:适配器模式不适合在系统设计阶段采用,没有一个系统分析师会在做详设的时候考虑使用适配器模式,这个模式使用的主要场景是扩展应用中。系统扩展了,不符合原有设计的时候才考虑通过适配器模式减少代码修改带来的风险。
5.C++代码实现:
#include<iostream>
#include<string> 
using namespace std;
//适配器基类 
class Target{
public:
Target()
{
//默认构造 
}
virtual void Request()
{
cout<<"普通的请求!"<<endl;
}
virtual ~Target()
{
cout<<"~Target!"<<endl;
}
};
// 与被Adapter对象提供不兼容接口的类
//旧系统,新系统通过适配器基类适配旧系统 
class Adaptee{
public:
Adaptee()
{
//默认构造 
}
~Adaptee()
{
cout<<"~Adaptee!"<<endl;
}
void SpecialRequest(string num)
{
cout <<"旧系统:这是Adaptee类型"<<num<<"请求!"<<endl;
}
};
// 进行Adaptee的类,采用聚合原有接口类的方式
//具体适配器 对象模式 
class Adapter:public Target{
private:
Adaptee* pAdptee;
public:
Adapter(Adaptee* pAdaptee): pAdptee(pAdaptee)
{

}
Adapter()
{
//pAdptee=new Adaptee();
}
virtual void Request()
{
//cout << "具体适配器:Adapter类型请求!"<<endl;
pAdptee->SpecialRequest("1");
}
virtual ~Adapter()
{
delete pAdptee;
pAdptee = NULL;
cout<<"~Adapter!"<<endl;
}
};
//类模式,适配器类,通过public继承获得接口继承的效果,通过private继承获得实现继承的效果
class Adapter1:public Target,private Adaptee{
public:
    Adapter1()
{

}     
~Adapter1()
{

}
      virtual void Request()//实现Target定义的Request接口
      {
      this->SpecialRequest("2");
      }
};


int main(void)
{
//类模式Adapter
  Target* pTarget = new Adapter1();
pTarget->Request();

//对象模式Adapter1 
Target* pTarget1 = new Adapter();
   pTarget1->Request();
   
//对象模式Adapter2
Adaptee* adaptee = new Adaptee();
   Target* pTarget2= new Adapter(adaptee);
   pTarget2->Request();
   
   delete pTarget;
   delete pTarget1;
   delete pTarget2;
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值