轉接器模式(Adapter Pattern)

轉接器模式:將一個類別的介面,轉換成另一個介面以供客戶使用,轉接器讓原本不相容的類別可以互相合作。

假使有一個既有的軟體系統,想要和新的廠商類別庫搭配使用,我們不能改變廠商提供的程式碼,如果也不想改變原本的系統,這時可以寫一個類別,將廠商的介面轉成和舊系統相容的介面。

下面例子有類別狼和狗,這兩個類別彼此不相容,我們建了一個轉接器,將狗類別的成員函式,讓狼類別去實作,而testDog()函式,可以接受轉接器和狗類別當參數,所以我們不需要改變類別,以及testDog()函式的程式碼,就能達到目的。

#include <iostream>
using namespace std;

class Dog{
public:
    virtual void bark(){ cout << "旺旺" << endl; }
    virtual void run(){ cout << "跑一段距離" << endl; }
};
class Wolf{
public:
    virtual void howl(){ cout << "嚎~~" << endl; }
    virtual void run(){ cout << "跑一大段距離" << endl; }
};
class WolfAdapter : public Dog{
private:
    Wolf *m_wolf;
public:
    WolfAdapter(Wolf *wolf){ m_wolf = wolf; }
    void bark(){ m_wolf->howl(); }
    void run(){ m_wolf->run(); }
};

void testDog(Dog *dog);

int main(){
    Dog myDog;
    Wolf myWolf;
    WolfAdapter myWolfAdapter(&myWolf);

    testDog(&myDog);
    testDog(&myWolfAdapter);

    return 0;
}

void testDog(Dog *dog){
    dog->bark();
    dog->run();
}

我們也可以設計一個雙向轉接器,讓他同時可當作兩個類別的介面,以下是簡單的示範。

#include <iostream>
using namespace std;

class Dog{
public:
    virtual void bark(){ cout << "旺旺" << endl; }
};
class Wolf{
public:
    virtual void howl(){ cout << "嚎~~" << endl; }
};
class Adapter : public Dog, public Wolf{
private:
    Wolf *m_wolf;
    Dog *m_dog;
public:
    Adapter(Wolf *wolf){ m_wolf = wolf; }
    Adapter(Dog *dog){ m_dog = dog; }
    void bark(){ m_wolf->howl(); }
    void howl(){ m_dog->bark(); }
};

void testDog(Dog *dog);
void testWolf(Wolf *wolf);

int main(){
    Dog myDog;
    Wolf myWolf;
    Adapter dogAdapter(&myWolf);
    Adapter wolfAdapter(&myDog);

    testDog(&dogAdapter);
    testWolf(&wolfAdapter);

    return 0;
}

void testDog(Dog *dog){
    dog->bark();
}
void testWolf(Wolf *wolf){
    wolf->howl();
}