天天看點

設計模式之類對象結構型 — BRIDGE (橋接)模式

意圖

将抽象部分與他的實作部分分離,使他們都可以獨立的變化

實作

參考我的這篇文章(點這裡),之前已經總結過了,就不重複了。

注意:之前僅僅是對代碼依賴性的考慮,這次是在之前的基礎上增加了控制不同實作的效果

代碼示例

注意:這是完整的示例代碼 vs2013編譯通過
//windows.h 檔案
#pragma once

#include <iostream>
using namespace std;

//使用聲明式   降低耦合
class WindowsImp;
class Windows
{
public:
    Windows();
    virtual ~Windows();

    virtual void paint(){};
    virtual void drawContents(){};

protected:
    WindowsImp *getWindowImp();

private:
    WindowsImp *m_imp;
};



class IcoWindows:public Windows
{
public:
    IcoWindows();
    ~IcoWindows();

    virtual void paint();
    virtual void drawContents();

private:
    //  
};


class ButtonWindows :public Windows
{
public:
    ButtonWindows();
    ~ButtonWindows();


    virtual void paint();
    virtual void drawContents();

private:
    //

};

//windows.cpp 檔案
#include "Windows.h"
#include "WindowsImp.h"
#include "WindowsFactory.h"

Windows::Windows()
:m_imp(NULL)
{

}


Windows::~Windows()
{
}

WindowsImp * Windows::getWindowImp()
{
    if (m_imp==NULL)
    {
        m_imp = WindowsFactory::Instance()->getMicWinImp();
    }
    return m_imp;
}


IcoWindows::IcoWindows()
{
}

IcoWindows::~IcoWindows()
{
}

void IcoWindows::paint()
{
    cout << "我是IcoWindows   paint()" << endl;
    //繼承至父類,擷取WindowsImp的執行個體
    this->getWindowImp()->deviceRect();
    return;
}

void IcoWindows::drawContents()
{
    cout << "我是IcoWindows   drawContents()" << endl;
    this->getWindowImp()->paintBitmap();
    return;
}


ButtonWindows::ButtonWindows()
{
}

ButtonWindows::~ButtonWindows()
{
}

void ButtonWindows::paint()
{
    cout << "我是ButtonWindows   paint()" << endl;
    this->getWindowImp()->deviceRect();
    return;
}

void ButtonWindows::drawContents()
{
    cout << "我是ButtonWindows   drawContents()" << endl;
    this->getWindowImp()->paintBitmap();
    return;
}


----------
//windowsImp.h 檔案
#pragma once

#include <iostream>
using namespace std;

/*Windows 類的實作類 */
class WindowsImp
{
public:
    virtual ~WindowsImp();

    virtual void paintBitmap() = ;
    virtual void deviceRect() = ;

protected:
    WindowsImp();
};

//微軟的版本  
class MicrosoftWindowsImp:public WindowsImp
{
public:
    MicrosoftWindowsImp();
    ~MicrosoftWindowsImp();

    virtual void paintBitmap();
    virtual void deviceRect();
private:

};

//蘋果系統的版本  
class AppleWindowsImp:public WindowsImp
{
public:
    AppleWindowsImp();
    ~AppleWindowsImp();

    virtual void paintBitmap();
    virtual void deviceRect();
private:

};


//windowsImp.cpp 檔案
#include "WindowsImp.h"


WindowsImp::WindowsImp()
{
}


WindowsImp::~WindowsImp()
{
}


MicrosoftWindowsImp::MicrosoftWindowsImp()
{
}

MicrosoftWindowsImp::~MicrosoftWindowsImp()
{
}

void MicrosoftWindowsImp::paintBitmap()
{
    cout << "微軟windows系統的  paintBitmap()" << endl;
    return;
}

void MicrosoftWindowsImp::deviceRect()
{
    cout << "微軟windows系統的  deviceRect()" << endl;
}


AppleWindowsImp::AppleWindowsImp()
{
}

AppleWindowsImp::~AppleWindowsImp()
{
}

void AppleWindowsImp::paintBitmap()
{
    cout << "蘋果Mac系統的  paintBitmap()" << endl;
    return;
}

void AppleWindowsImp::deviceRect()
{
    cout << "蘋果Mac系統的  deviceRect()" << endl;
    return;
}


----------
//WindowsFactory.h檔案
#pragma once
#include <iostream>
using namespace std;

class WindowsImp;
class MicrosoftWindowsImp;
class AppleWindowsImp;

class WindowsFactory
{
public:
    WindowsFactory();
    ~WindowsFactory(); 
    //工廠方法 
    WindowsImp * getMicWinImp();   //建立微軟windows版本的執行個體
    WindowsImp * getAppMacImp();   //建立蘋果Mac版本的執行個體  

    /* 這裡使用了 兩個方法  來區分不同的系統版本對應的實作代碼 */
    /* 也可以通過宏定義 使用一個工廠方法就可以 自動的對應實作的代碼 */
    /* 也可以在建立Windows類的具體類的執行個體是 通過傳入參數,來控制版本,總之方法很多  */

    //單例模式   
    static WindowsFactory * Instance();
private:
    static WindowsFactory *m_win;

    MicrosoftWindowsImp * m_micWin;
    AppleWindowsImp * m_appWin;
};


//WindowsFactory.cpp檔案

#include "WindowsFactory.h"
#include "WindowsImp.h"

WindowsFactory::WindowsFactory()
:m_micWin(NULL), m_appWin(NULL)
{
}


WindowsFactory::~WindowsFactory()
{
}

WindowsImp * WindowsFactory::getMicWinImp()
{
    if (m_micWin==NULL)
    {
        m_micWin = new MicrosoftWindowsImp();
    }
    return m_micWin;
}

WindowsImp * WindowsFactory::getAppMacImp()
{
    if (m_appWin==NULL)
    {
        m_appWin = new AppleWindowsImp();
    }
    return m_appWin;
}

WindowsFactory * WindowsFactory::Instance()
{
    if (m_win == NULL)
    {
        m_win = new WindowsFactory();
    }
    return m_win;
}
WindowsFactory * WindowsFactory::m_win=NULL;


----------
//main.cpp檔案

#include "Windows.h"
int main()
{
    IcoWindows ico;
    ico.drawContents();
    ico.paint();

    cout << "\n------------------------\n" << endl;

    ButtonWindows butt;
    butt.drawContents();
    butt.paint();

    getchar();
    return ;
}
           

代碼解析

  • windows類是 視窗控件的抽象類 IcoWindows 類和 ButtonWIndows 類是他的具體子類,代表兩種不同的控件
  • windowsImp 類是 windows類的實作類 他的兩個子類分别對應兩個不同的實作版本

    使用 windowsImpFactory 類的工廠方法來執行個體化 windowsImp 的子類

    -windows類中的getWindowImp()方法來傳回WindowsImp的執行個體

    windowsImpFactory 類使用了 單例模式

檔案依賴圖
設計模式之類對象結構型 — BRIDGE (橋接)模式

效果

  • 分離了接口及其實作部分,降低編譯的依賴性
  • 提高了可擴充性
  • 隐藏了實作細節

我的個人網站 http://www.breeziness.cn/

我的CSDN http://blog.csdn.net/qq_33775402

轉載請注明出處 小風code www.breeziness.cn

繼續閱讀