C++設計模式——橋接模式

前言:最近在看面向對象程序設計時,遇到了幾個新鮮的設計模式於是查了查資料,最終把他搞明白了,還是很開心的。。。

橋接模式

橋接模式的定義是這樣的:

1、GOF四人幫在《設計模式:可複用面向對象軟件的基礎》一書中是這樣描述的(見下引用),現在聽起來感覺雲裏霧裏的,不要在這裏糾結,我們接着往下。

將抽象部分和它的實現部分分離,使它們都可以獨立的變化。簡單粗暴的說,就是抽象對外提供調用的接口;對外隱瞞實現部分,在抽象中引用實現部分,從而實現抽象對實現部分的調用,而抽象中引用的實現部分可以在今後的開發過程中,切換成別的實現部分(《設計模式:可複用面向對象軟件的基礎》)


2、《大話設計模式》一書中是這樣描述的(見下引用)

將抽象部分與他的實現部分分離,使他們都可以獨立的變化(《大話設計模式》)

UML類圖

橋接模式UML圖

實例

1、繪製紅色的長方形、白色的圓形(Jelly Young:C++設計模式——橋接模式
/*
** FileName     : BridgePatternDemo
** Author       : Jelly Young
** Date         : 2013/12/4
** Description  : More information (http://www.jellythink.com/)
** Author       : Aidan Dai
** Date         : 2015/11/20
** Description  : 添加註釋(http://www.jellythink.com/archives/132)
*/

#include <iostream>
using namespace std;

/*
**  實現(顏料)
*/
class Implementor
{
public:
    virtual void OperationImpl() = 0;
};

/*
**  具體實現(黃色顏料、綠色顏料、藍色顏料)
*/
class ConcreteImpementor : public Implementor
{
public:
    void OperationImpl()
    {
        cout << "OperationImpl" << endl;
    }
};

/*
**  抽象(平面圖形)
**  維護一個指向具體實現的指針(黃色顏料、綠色顏料、藍色顏料)
*/
class Abstraction
{
public:
    Abstraction(Implementor *pImpl) : m_pImpl(pImpl){}
    virtual void Operation() = 0;
protected:
    Implementor *m_pImpl;
};

/*
**  被提煉的抽象(圓形、正方形、長方形)
*/
class RedfinedAbstraction : public Abstraction
{
public:
    RedfinedAbstraction(Implementor *pImpl) : Abstraction(pImpl){}
    void Operation()
    {
        m_pImpl->OperationImpl();
    }
};

int main(void)
{
    Implementor *pImplObj = new ConcreteImpementor();
    Abstraction *pAbsObj = new RedfinedAbstraction(pImplObj);

    pAbsObj->Operation();

    delete pImplObj;
    pImplObj = NULL;

    delete pAbsObj;
    pAbsObj = NULL;

    return 0;
}
2、手機軟件何時統一(《大話設計模式》)
#include <iostream>
#include <string>

using namespace std;

class Implementor{
public:
    void virtual Operation() = 0;
};

class ConcreteImplementorA : public Implementor{
public:
    void Operation(){
        cout << "ConcreteImplementorA" << endl;
    }
};

class ConcreteImplementorB : public Implementor{
public:
    void Operation(){
        cout << "ConcreteImplementorB" << endl;
    }
};

class Abstraction{
public:
    void SetImplementor(Implementor *implementor){
        this->m_implementor = implementor;
    }
    void virtual Operator() = 0;
protected:
    Implementor *m_implementor;
};

class RefinedAbstraction : public Abstraction{
public:
    void Operator(){
        this->m_implementor->Operation();
    }
};

int main(void){
    Abstraction *abstraction = new RefinedAbstraction();

    Implementor *implementor1 = new ConcreteImplementorA();

    abstraction->SetImplementor(implementor1);
    abstraction->Operator();

    Implementor *implementor2 = new ConcreteImplementorB();

    abstraction->SetImplementor(implementor2);
    abstraction->Operator();

    delete abstraction;
    abstraction = NULL;

    delete implementor1;
    implementor1 = NULL;

    delete implementor2;
    implementor2 = NULL;


    return 0;
}
3、自由切換家用電器開關(我給媳婦解釋設計模式:第一部分(譯文)
#include <iostream>
#include <string>

using namespace std;

class Equipment{
public:
    void virtual poweron(string switchName) = 0;
    void virtual poweroff(string switchName) = 0;
};

class Fan :public Equipment{
public:
    void poweron(string switchName){
        cout << "poweron Fan by " << switchName << endl;
    }
    void poweroff(string switchName){
        cout << "poweroff Fan by " << switchName << endl;
    }
};

class Light :public Equipment{
public:
    void poweron(string switchName){
        cout << "poweron Light by " << switchName << endl;
    }
    void poweroff(string switchName){
        cout << "poweroff Light by " << switchName << endl;
    }
};

class Switch{
public:
    Switch(Equipment *equipment){
        this->m_equipment = equipment;
    }
    void virtual on() = 0;
    void virtual off() = 0;
    Equipment *m_equipment;
};

class NormalSwitch :public Switch{
public:
    NormalSwitch(Equipment *equipment) :Switch(equipment){
        this->m_switchName = "NormalSwitch";
    }
    void on(){
        this->m_equipment->poweron(this->m_switchName);
    }
    void off(){
        this->m_equipment->poweroff(this->m_switchName);
    }
private:
    string m_switchName;
};

class FancySwitch :public Switch{
public:
    FancySwitch(Equipment *equipment) :Switch(equipment){
        this->m_switchName = "FancySwitch";
    }
    void on(){
        this->m_equipment->poweron(this->m_switchName);
    }
    void off(){
        this->m_equipment->poweroff(this->m_switchName);
    }
private:
    string m_switchName;
};

int main(void){

    Equipment *equipment1 = new Fan();
    Equipment *equipment2 = new Light();

    Switch *equipmentSwitch1 = new NormalSwitch(equipment1);
    Switch *equipmentSwitch2 = new FancySwitch(equipment2);
    Switch *equipmentSwitch3 = new NormalSwitch(equipment1);
    Switch *equipmentSwitch4 = new FancySwitch(equipment2);

    equipmentSwitch1->on();
    equipmentSwitch1->off();

    equipmentSwitch2->on();
    equipmentSwitch2->off();

    equipmentSwitch3->on();
    equipmentSwitch3->off();

    equipmentSwitch4->on();
    equipmentSwitch4->off();

    delete equipment1;
    equipment1 = NULL;

    delete equipment2;
    equipment2 = NULL;

    delete equipmentSwitch1;
    delete equipmentSwitch2;
    delete equipmentSwitch3;
    delete equipmentSwitch4;

    equipmentSwitch1 = NULL;
    equipmentSwitch2 = NULL;
    equipmentSwitch3 = NULL;
    equipmentSwitch4 = NULL;

    return 0;
}

總結

is a 和 has a

1、理解繼承:

  • 對象的繼承關係是在編譯時就定義好了,所以無法再無法再運行時改變從父類繼承的實現。子類的實現與它的父類有非常緊密的的依賴關係,以至於父類的實現中的任何變化必然會導致子類發生變化。當你需要複用子類時,如果繼承下來的實現不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關係限制了靈活性並最終限制了複用性。

2、理解合成/聚合複用原則

  • 合成/聚合複用原則:聚合表示一種弱的“擁有”關係,體現的是A對象可以包含B對象,但B對象不是A對象的一部分;合成則是一種強的“擁有”關係,體現了嚴格的部分和整體的關係,部分和整體的生命週期是一樣的[DRE]

就像大雁、翅膀和雁羣的關係:
這裏寫圖片描述

3、降低代碼耦合度

4、通過實例不斷的運用

結束語:

夢想還是要有的,萬一實現了了呢!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章