深入淺出設計模式原則之依賴倒置原則

下面以“顧客購物程序”爲例來說明依賴倒置原則的應用。

#include <QCoreApplication>
#include <iostream>

//! shop
class Shop{
public:
    virtual std::string Sell() = 0;
};

class ShaoguanShop:public Shop{
public:
    std::string Sell(){
        return "shaoguan shop";
    }
};

class WuyanShop:public Shop{
public:
    std::string Sell(){
        return "wuyan shop";
    }
};

//! 顧客
class Customer {
public:
    void Shopping(Shop *shop){
        std::cout<<shop->Sell()<<std::endl;
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    class Customer wang;
    ShaoguanShop myShaoguanShop;
    WuyanShop    myWuyanShop;
    wang.Shopping(&myShaoguanShop);
    wang.Shopping(&myWuyanShop);
    return a.exec();
}

分析:本程序反映了 “顧客類”與“商店類”的關係。商店類中有 sell() 方法,顧客類通過該方法購物以下代碼定義了顧客類通過韶關網店 ShaoguanShop 購物:

class Customer {
public:
    void Shopping(ShaoguanShop *shop){
        std::cout<<shop->Sell()<<std::endl;
    }
};

但是,這種設計存在缺點,如果該顧客想從另外一家商店(如婺源網店 WuyuanShop)購物,就要將該顧客的代碼修改如下:

class Customer {
public:
    void Shopping(WuyanShop*shop){
        std::cout<<shop->Sell()<<std::endl;
    }
};

顧客每更換一家商店,都要修改一次代碼,這明顯違背了開閉原則。存在以上缺點的原因是:顧客類設計時同具體的商店類綁定了,這違背了依賴倒置原則。解決方法是:定義“婺源網店”和“韶關網店”的共同接口 Shop,顧客類面向該接口編程,其代碼修改如下:

//! 顧客
class Customer {
public:
    void Shopping(Shop *shop){
        std::cout<<shop->Sell()<<std::endl;
    }
};

 這樣,不管顧客類 Customer 訪問什麼商店,或者增加新的商店,都不需要修改原有代碼了,其類圖如圖 1 所示。

顧客購物程序的類圖

 

 這個原則是開閉原則的基礎,具體內容:針對接口編程,依賴於抽象而不依賴於具體。

參考:

  1. 依賴倒置原則——面向對象設計原則
  2. 面向對象六大原則——依賴倒置原則

 

 

 

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