下面以“顧客購物程序”爲例來說明依賴倒置原則的應用。
#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 所示。
這個原則是開閉原則的基礎,具體內容:針對接口編程,依賴於抽象而不依賴於具體。
參考: