C++ - Adapter模式

来源:互联网 发布:盐城大数据产业园详址 编辑:程序博客网 时间:2024/06/06 00:23
 
设计模式 - C++ - Adapter模式
1. 适配器(Adapter模式、Wrapper模式、包裹器模式)的现实意义
        (1) 手机充电:现在的手机数据线一般可以充当着充电连接线的角色。我们需要充电的时候只要把数据线接上电脑USB口即可。如果身边没有电脑,则可以将数据线连上电源适配器,然后插入我们国家伟大的220V电源进行充电。这个电源适配器充当的角色其实很清晰,适配了两种不同的介入方式。适配的结果就是将220V交流电源转换成几V的电压然后传入原始接口(电源线USB接口)
        (2) 插头转换器:我们的电脑电源线的插头一般是三头的插头,倘若有一天我们到了一个地方,墙上只有一个2孔插口,那种看得见吃不着的感觉诸位看官应该都有体会过吧。这时候怎么办呢?一种方法是可以买一个带3孔的插座;另一种就是用插孔转换器将3孔转换为2孔然后介入令人舒服的220V。在这里插座和转换器都起了适配器的角色。其中插座适配了墙上2孔插座的接口;转换器适配了电脑电源插头2头的接口。
        因此按这样看来,当AB两个接口进行对接的时候,如果接口协议不一致,那么我们可以适配A的接口也可以适配B的接口。适配器的作用就是进行接口转换。

2. 适配器的种类
        (1)对象适配器模式(组合)
        适配器容纳一个它我包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。

       (2)类适配器模式(继承)
       适配器继承自已要适配的类


2. 适配器模式的组成元素
        (1) 目标抽象角色(Target):定义客户所期待要使用的接口,这是一个抽象的设备,主要是形成一种接口规约,满足这种规约的接口的设备都能满足客户。
        (2) 源角色(Adaptee):需要被适配的接口,比如手机数据线和电脑电源插头。
        (3) 适配器角色(Adapter):用来把源接口转换成符合要求的目标接口的设备,比如电源转换器和插头转换器。
        (4) 客户端(Client):客户是爷,我们只能装孙子,客户要求这么玩,于是我们就得这么玩,不然您让客户适配去。

3. 适配器适用范围
        对于类适配器:
       (1)  用一个具体的Adapter类对Adaptee和Taget进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作。
       (2)  Adapter可以override Adaptee的部分行为。
       对于对象适配器:
        (1) 允许一个Adapter与多个Adaptee,即Adaptee本身以及它的所有子类(如果有子类的话)同时工作。Adapter也可以一次给所有的Adaptee添加功能。
        (2) 使得override Adaptee的行为比较困难。如果一定要override Adaptee的方法,就只好先做一个Adaptee的子类以override Adaptee的方法,然后再把这个子类当作真正的Adaptee源进行适配。

4. 适配器案例
        (1) STL:function adapter、iterator adpter

5. 不实用的教程代码(:) 挖自金山师兄博客http://www.cnblogs.com/whiteyun/archive/2010/11/27/1889743.html)
    (1) object Adapter pattern
    Adapter.h
 1 #ifndef ADAPTER_H
 2 #define ADAPTER_H
 3 
 4 // 需要被Adapt的类
 5 class Target
 6 {
 7 public:
 8     Target(){}
 9     virtual ~Target() {}
10 
11     virtual void Request() = 0;
12 };
13 
14 // 与被Adapt对象提供不兼容接口的类     chris 说:这是规约,客户要怎么玩的规则
15 class Adaptee
16 {
17 public:
18     Adaptee(){}
19     ~Adaptee(){}
20     void SpecialRequest();
21 };
22 
23 // 进行Adapt的类,采用聚合原有接口类的方式
24 class Adapter
25     : public Target               //  chris 说:继承规约
26 {
27 public:
28     Adapter(Adaptee* pAdaptee);
29     virtual ~Adapter();
30 
31     virtual void Request();
32 
33 private:
34     Adaptee* m_pAdptee;
35 };
36 
37 #endif

    Adapter.cpp
 1 #include "Adapter.h"
 2 #include <iostream>
 3 
 4 void Adaptee::SpecialRequest()
 5 {
 6     std::cout << "SpecialRequest of Adaptee\n";
 7 }
 8 
 9 Adapter::Adapter(Adaptee* pAdaptee)
10     : m_pAdptee(pAdaptee)
11 {
12 
13 }
14 
15 Adapter::~Adapter()
16 {
17     delete m_pAdptee;
18     m_pAdptee = NULL;
19 }
20 
21 void Adapter::Request()
22 {
23     std::cout << "Request of Adapter\n";
24 
25     m_pAdptee->SpecialRequest();
26 }

    (2) class Adapter pattern
class Adaptee
{
public:
    void SpecialRequest() {}
} ;

class Target
{
public:
    virtual void Request() = 0 ;
} ;

class Adapter : public Target, private Adaptee
{
public:
    virtual void Request() { SpecialRequest() ; }
} ;

6. 实用适配器模式代码
问题:假设有几个已有类,他们有某些共同的行为,但它们彼此间是独立的(没有共同的基类)。如:
class T1
{
public:
    void Proc() {}
} ;
class T2
{
public:
    void Proc() {}
} ;

// 采用模板技术解决 
class Target
{
public:
     Target(){}
     virtual ~Target() {} 
     virtual void Request() = 0;
};

template <class T>
class Adaptor : public Target, private T   // 继承规约
{
public:
    virtual void Request() { T::Proc() ; }
} ;
原创粉丝点击