設計模式 - 橋模式(Bridge)

    在軟件設計中,如果責任劃分不清晰,需求的變化時,子類會急劇膨脹,代碼會大量重複。此時,劃分責任是最關鍵的做法。

定義

    橋模式將“抽象部分”與“實現部分”分離,使它們獨立的變化。

實例

    先看下面代碼存在的問題。(子類膨脹,重複代碼)

    在PC平臺和Mobile平臺分別實現文本和圖片的生成和發送。

    消息的基類如下:

class Messager
{
public:
    virtual void SendText(string text) = 0;
    virtual void SendPicture(string Image) = 0;

   
    virtual void PlaySound() = 0;
    virtual void DrawText() = 0;
    virtual void DrawPicture() = 0;
    virtual ~Messager(){}
};

    PC平臺的實現如下:

//PC平臺
class PCMessager:public Messager
{
public:
    virtual void PlaySound() override {}
    virtual void DrawText() override {}
    virtual void DrawPicture() override {}
    virtual ~PCMessager(){}
};

//精簡版
class PCMessagerLite :public PCMessager
{
public:
    virtual void SendText(string text) override
    {
        PCMessager::DrawText();
    }
    virtual void SendPicture(string Image) override
    { 
        PCMessager::DrawPicture();
    }
    virtual ~PCMessagerLite() {}
};

//完美版
class PCMessagerPerfect :public PCMessager
{
public:
    virtual void SendText(string text) override
    {
        PCMessager::PlaySound();
        PCMessager::DrawText();
    }

    virtual void SendPicture(string Image) override
    {
        PCMessager::PlaySound();
        PCMessager::DrawPicture();
    }
    virtual ~PCMessagerPerfect(){}
};

    Mobile平臺的實現如下:

//Mobile平臺
class MobileMessager :public Messager
{
public:
    virtual void PlaySound()override {}
    virtual void DrawText() override {}
    virtual void DrawPicture() override {}
    virtual ~MobileMessager(){}
};
//精簡版
class MobileMessagerLite :public MobileMessager
{
public:

    virtual void SendText(string text) override
    {
        MobileMessager::DrawText();
    }
    virtual void SendPicture(string Image) override
    {
        MobileMessager::DrawPicture();
    }

    virtual ~MobileMessagerLite(){}
};
//完美版
class MobileMessagerPerfect :public MobileMessager
{
public:
    virtual void SendText(string text) override
    {
        MobileMessager::PlaySound();
        MobileMessager::DrawText();
    }

    virtual void SendPicture(string Image) override
    {
        MobileMessager::PlaySound();
        MobileMessager::DrawPicture();
    }
    virtual ~MobileMessagerPerfect() {}
};

 上述代碼中存在大量的重複代碼,原因是將messager的兩個方向上的變化混在了一起,使用了繼承而不是組合的方式組織代碼。

 下面使用橋模式改進代碼:

  平臺實現:

class MessagerImp
{
public:
    virtual void PlaySound() = 0;
    virtual void DrawText() = 0;
    virtual void DrawPicture() = 0;
    virtual ~MessagerImp() {}
};

//PC平臺
class PCMessagerImp :public MessagerImp
{
public:
    virtual void PlaySound()override {}
    virtual void DrawText() override {}
    virtual void DrawPicture() override {}
    virtual ~PCMessagerImp() {}
};

//Mobile平臺
class MobileMessagerImp :public MessagerImp
{
public:
    virtual void PlaySound()override {}
    virtual void DrawText() override {}
    virtual void DrawPicture() override {}
    virtual ~MobileMessagerImp() {}
};

    業務實現:


class Messager
{
public:
    virtual void SendText(string text) = 0;
    virtual void SendPicture(string Image) = 0;  
    virtual ~Messager(){}
protected:
    MessagerImp *messagerImp;
};

//精簡版
class MessagerLite: public Messager
{
public:
    virtual void SendText(string text) override
    {
        messagerImp->DrawText();
    }
    virtual void SendPicture(string Image) override
    {
        messagerImp->DrawPicture();
    }
    virtual ~MessagerLite() {}  
};

//完美版
class MessagerPerfect: public Messager
{
public:
    virtual void SendText(string text) override
    {
        messagerImp->PlaySound();
        messagerImp->DrawText();
    }

    virtual void SendPicture(string Image) override
    {
        messagerImp->PlaySound();
        messagerImp->DrawPicture();
    }
    virtual ~MessagerPerfect() {}
};

  橋模式的類圖如下:

       

總結 

    橋模式使用“對象間的組合關係”解耦了抽象和實現兩個維度的變化。

 

 

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