设计模式 - C++ - Adapter模式
1. 适配器(Adapter模式、Wrapper模式、包裹器模式)的现实意义
(1) 手机充电:现在的手机数据线一般可以充当着充电连接线的角色。我们需要充电的时候只要把数据线接上电脑USB口即可。如果身边没有电脑,则可以将数据线连上电源适配器,然后插入我们国家伟大的220V电源进行充电。这个电源适配器充当的角色其实很清晰,适配了两种不同的介入方式。适配的结果就是将220V交流电源转换成几V的电压然后传入原始接口(电源线USB接口)
(2) 插头转换器:我们的电脑电源线的插头一般是三头的插头,倘若有一天我们到了一个地方,墙上只有一个2孔插口,那种看得见吃不着的感觉诸位看官应该都有体会过吧。这时候怎么办呢?一种方法是可以买一个带3孔的插座;另一种就是用插孔转换器将3孔转换为2孔然后介入令人舒服的220V。在这里插座和转换器都起了适配器的角色。其中插座适配了墙上2孔插座的接口;转换器适配了电脑电源插头2头的接口。
因此按这样看来,当AB两个接口进行对接的时候,如果接口协议不一致,那么我们可以适配A的接口也可以适配B的接口。适配器的作用就是进行接口转换。
2. 适配器的种类
(1)对象适配器模式(组合)
适配器容纳一个它我包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。
![](http://hi.csdn.net/attachment/201107/19/0_1311059181wnno.gif)
(2)类适配器模式(继承)
适配器继承自已要适配的类
![](http://hi.csdn.net/attachment/201107/19/0_1311059099riMk.gif)
2. 适配器模式的组成元素
(1) 目标抽象角色(Target):定义客户所期待要使用的接口,这是一个抽象的设备,主要是形成一种接口规约,满足这种规约的接口的设备都能满足客户。
(2) 源角色(Adaptee):需要被适配的接口,比如手机数据线和电脑电源插头。
(3) 适配器角色(Adapter):用来把源接口转换成符合要求的目标接口的设备,比如电源转换器和插头转换器。
(4) 客户端(Client):客户是爷,我们只能装孙子,客户要求这么玩,于是我们就得这么玩,不然您让客户适配去。
(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源进行适配。
(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
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 }
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() ; }
} ;
{
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() {}
} ;
{
public:
void Proc() {}
} ;
class T2
{
public:
void Proc() {}
} ;
// 采用模板技术解决
class Target
{
public:
Target(){}
virtual ~Target() {}
virtual void Request() = 0;
{
public:
Target(){}
virtual ~Target() {}
virtual void Request() = 0;
};
template <class T>
class Adaptor : public Target, private T // 继承规约
{
public:
virtual void Request() { T::Proc() ; }
} ;
class Adaptor : public Target, private T // 继承规约
{
public:
virtual void Request() { T::Proc() ; }
} ;