C++设计模式-适配器(转)

转:http://www.shenmiguo.com/archives/2009/296_design-patterns-adapter.html





C++设计模式-适配器

 定义

将一个类的接口转换成客户希望的另外一个接口。适配器(Adapter )模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。也叫包装器( Wrappter )。
 
结构
对象适配器(Object Adapter ),使用对象组合方式:
对象适配器
 
类适配器(Class Adapter ),使用类继承方式:
类适配器
 
理解
1.      Target 是供Client 调用的抽象基类。
2.      Adaptee 是需要适配的类(适配者类)。Adaptee 的方法(SpecificRequest )与Target 的方法(Request )是不兼容的。
3.      Adapter 是适配器类。完成对Target Adaptee 的接口适配工作。Adapter 重新实现Request 方法,内部隐藏了调用Adaptee 不兼容方法(SpecificRequest )的细节。
4.       类适配器 是通过继承类适配者类(Adaptee )实现的。类适配器实现客户类所需要的方法(SpecificRequest )。当客户对象调用适配器类(Adapter )方法的时候,适配器内部调用它所继承的适配者的方法。
5.       对象适配器 包含一个适配器者的引用,与类适配器相同,对象适配器也实现了客户类需要的接口。当客户对象调用对象适配器的方法的时候,对象适配器调它所包含的适配器者实例的适当方法。对象组合方式,允许一个Adapter 适配多个Adaptee
 
要点
1.       适配器模式适用于:
你想使用一个已经存在的类,而它的接口不符合你的需求。
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
(仅适用于对象适配器)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
2.       C++ 使用类适配器时 Adapter类使用public方式继承Target类,并使用private方式继承Adaptee 类。这样,Adapter Target 子类型,但不是Adaptee 子类型。如此这般,推荐使用对象适配器方式。
3.       适配器模式与桥接( Bridge )模式的区别 。桥接模式的目的是将接口部分与实现分离,从而使它们能相对独立的改变;桥接是设计阶段行为。适配器模式是对已有接口的改变,使得功能相同但接口不兼容的类桥接在一起。
 
应用
在中国大陆,使用中式插座(CCnOutlet )。买了一个水货手机,但充电器使用英式插座(CEnOutlet )。要想在中式插座上给手机充电,就得买一个插座转换器(CCnOutletAdapter )来,使两个不匹配的接口可以正常工作。插座转换器就是适配器(Adapter ),英式插座是适配者(Adaptee )。
源码中使用对象适配器方式,这样的好处是,适配器可以有多个适配者,譬如我要兼容美式插座,只需要新增 美式 插座CUsOutlet ,并且将CUsOutlet 作为CCnOutletAdapter 的成员即可。
 
源码
#include <iostream>
#include <string>
using namespace std;
 
// 适配器基类 Target, 中式插座
class CCnOutlet
{
public :
    virtual ~CCnOutlet(){};
 
    virtual void CnPlug(){};
};
 
// 适配者 Adaptee, 英式插头
class CEnOutlet
{
public :
    void EnPlug()
    {
        cout <<"use en plug" <<endl;
    }
};
 
// 适配器 Adapter. 使用对象适配器方式
class CCnOutletAdapter : public CCnOutlet
{
public :
    CCnOutletAdapter(CEnOutlet*pEnOutlet) :m_pEnOutlet(pEnOutlet) {};
 
    virtual ~CCnOutletAdapter(){};
 
    virtual void CnPlug()
    {
        cout <<"wanna use cn plug" <<endl;
        cout <<"adapter transfer …" <<endl;
        m_pEnOutlet->EnPlug();
    }
 
protected :
    CEnOutlet*m_pEnOutlet;
};
 
int main()
{
    // 适配者当作参数传递给适配器,完成适配过程
    CEnOutlet*pEnOutlet =newCEnOutlet;
    CCnOutlet*pCnOutlet =newCCnOutletAdapter(pEnOutlet);
    pCnOutlet->CnPlug();
 
    delete pEnOutlet;
    delete pCnOutlet;
 
    system("pause");
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值