一、Adapter功能
将一个类的接口(待匹配接口)转换成客户希望的另外一个接口(目标接口),解决两个已有接口之间不匹配的问题。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
实质上过程是adaptee(待匹配类)---->adapter(匹配类)---->target(模板类),target类中的接口才是客户希望要的接口。
二、结构图
Adapter有两种模式:class adapter和object adapter,笔者翻译为类匹配和对象匹配;
class adapter
object adapter
图中的Client、Target、Adapter、Adaptee都表示类,里面的都是方法接口,特别三角符号表示继承关系。
三、示例代码
class adapter
// 待匹配的接口
class Adaptee
{
public:
void SpecialRequest() {};
} ;
// 目标接口,靠匹配类去实现目标的接口
class Target
{
public:
virtual void Request() = 0 ;
} ;
// 匹配类,实现目标接口,并通过继承方式调用父类接口的方式去匹配Adaptee接口
class Adapter : public Target, private Adaptee
{
public:
virtual void Request(){SpecialRequest() ; }
} ;
客户端代码:
Target *p = new Adapter() ;
p->Request() ; //实际上调用的是Adaptee::SpecialRequest()
object adapter
// 待匹配的接口
class Adaptee
{
public:void SpecialRequest() {};
} ;
// 目标接口,靠匹配类去实现目标的接口</span>
class Target
{
public:virtual void Request() = 0 ;
} ;
// 匹配类,实现目标接口,并通过调用待匹配类对象方法的方式去匹配Adaptee接口</span>
class Adapter : public Target
{
public:virtual void Request()
{
_adaptee.SpecialRequest() ;
}
private:Adaptee _adaptee ;
} ;
客户端代码:
Target *p = new Adapter() ;p->Request() ; //实际上调用的是Adaptee::SpecialRequest()
四、应用拓展
问题:假设有几个已有类,他们有某些共同的行为,但它们彼此间是独立的(没有共同的基类)。如何以统一的方式去调用这些行为呢?
|
解决方法1:很自然的会想到用模板,如:
|
这只适用于简单的情况,有时情况是很复杂的,比如我们无法把类型放到模板参数中!
解决方法2:困难来自于这些类没有共同的基类,所以我们就创造一个基类,然后再Adapter。
// 我们抽象出来的基类class IAdaptor
{
public :
virtual void Proc() = 0 ;
} ;
// 匹配类
template < class T>
class Adaptor : public IAdaptor, private T //实现继承,T为上面的T1或则T2
{
public :
virtual void Proc() { T::Proc() ; }
} ;
// 以统一方式调用函数Proc,而不关心是T1、T2或其他什么类,因为他们都有Prop()
class Target
{
void Test(const std::auto_ptr& sp)
{
sp->Proc() ;
}
}
客户端代码:
Test(std::auto_ptr(new Adaptor)) ;
Test(std::auto_ptr(new Adaptor)) ;
上例很简单,用方法一中的模板函数就可以很好地解决了。下面是一个略微复杂一点的例子,根据参数类型来创建适当的对象:
class T1 class T2 // class IAdaptor,抽象基类 // class Adaptor //两种构造函数,并根据参数类型不同去实例化不同的T class Test void Proc() { sp->Proc() ; } 客户端代码: Test t2('c') ; |