設計模式 - C++ - Adapter模式

設計模式 - 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() ; }
} ;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章