C++ 设计模式之Adaptor

一、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()

 四、应用拓展 

问题:假设有几个已有类,他们有某些共同的行为,但它们彼此间是独立的(没有共同的基类)。如何以统一的方式去调用这些行为呢? 

class T1
{
public:
void Proc() {}
} ;
class T2
{
public:
void Proc() {}
} ;
// ...

解决方法1:很自然的会想到用模板,如:

template <class T>
void Test(T t)
{
t.Proc() ;
}

这只适用于简单的情况,有时情况是很复杂的,比如我们无法把类型放到模板参数中!

解决方法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
{
public:
T1(int) { }
void Proc() { }
} ;

class T2
{
public:
T2(char) { }
void Proc() { }
} ;

// class IAdaptor,抽象基类
class IAdaptor
{
public:
virtual void Proc() = 0 ;
} ;

// class Adaptor
template 
class Adaptor : public IAdaptor, private T //实现继承,T为T1或者T2
{
public:

//两种构造函数,并根据参数类型不同去实例化不同的T
Adaptor(int n) : T(n) {}
Adaptor(char c) : T(c) {}
virtual void Proc() { T::Proc() ; }
} ;

class Test
{
public:
Test(int n) : sp(new Adaptor(n)) {}
Test(char c) : sp(new Adaptor(c)) {}

void Proc() { sp->Proc() ; }
private:
std::auto_ptr sp ;
} ;

客户端代码:
Test t1(10) ;
t1.Proc() ;

Test t2('c') ;
t2.Proc() ;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值