模式概述
在软件开发中,系统的数据和行为都正确,但接口不符合时,我们应该考虑使用适配器,目的是使得控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现有的类,但是接口又与复用环境要求不一致的情况,比如在需要早期代码复用一些功能等应用上很有实际价值。适配器模式的定义如下:
适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式将使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式中有类适配器和对象适配器两种类别,在项目中更推荐使用对象适配器,其结构体如下:
该模式中主要包含以下几个角色:
CTarget(目标接口): 这个是客户所期待的目标接口,可以是具体类,也可以是抽象类。
CAdapter(适配器类):这个充当适配器,在该角色的内部包含CAdaptee对象,该对象将源接口转换成目标接口,适配器类是适配器模式的核心。
CAdaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可能没有适配者类的源代码
据对象适配器模式结构图,在对象适配器中,客户端需要调用request()方法,而适配者类CAdaptee没有该方法,但是它所提供的specificRequest()方法却是客户端所需要的。为了使客户端能够使用适配者类,需要提供一个包装类CAdapter,即适配器类。这个包装类包装了一个适配者的实例,从而将客户端与适配者衔接起来,在适配器的request()方法中调用适配者的specificRequest()方法。
示例代码
主体代码:
#include "stdafx.h"
using namespace std;
//目标接口
class CTarget
{
public:
CTarget(){}
virtual ~CTarget(){}
virtual void Request() = 0;
};
//现存类
class CAdeptee
{
public:
CAdeptee(){}
~CAdeptee(){}
//执行请求任务
void SpecificalRequest()
{
cout << "call SpecificalRequest function" << endl;
}
};
//适配器类
class CAdpter:public CTarget
{
public:
CAdpter()
{
pAdeptee = new CAdeptee();
}
~CAdpter()
{
SAFE_DELETE_PTR(pAdeptee);
};
//目标接口,将实际接口和目标接口的差异进行封装
virtual void Request()
{
pAdeptee->SpecificalRequest();
}
private:
CAdeptee* pAdeptee;
};
客户端 :
CTarget* pTarget = new CAdpter();
pTarget->Request();
SAFE_DELETE_PTR(pTarget);
运行结果:
call SpecificalRequest function
模式总结
使用场景
在以下情况下可以考虑使用适配器模式:
(1) 系统需要使用一些现有的类,而这些类的接口(如方法名)不符合系统的需要,甚至没有这些类的源代码。
(2) 想创建一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
模式优点
(1) 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
(2) 增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用。
(3) 一个对象适配器可以把多个不同的适配者适配到同一个目标;
(4) 可以适配一个适配者的子类,由于适配器和适配者之间是关联关系,根据“里氏代换原则”,适配者的子类也可通过该适配器进行适配