您好,登錄后才能下訂單哦!
◆ 1.為了提高內聚(Cohesion)和松耦合(Coupling),我們經常會抽象出一些類的公共接口以形成抽象基類或者接口。這樣我們可以通過聲明一個指向基類的指針來指向實際的子類實現,達到了多態的目的。這里很容易出現的一個問題 n 多的子類繼承自抽象基類,我們不得不在每次要用到子類的地方就編寫諸如 new ×××;的代碼。這里帶來兩個問題:
客戶程序員必須知道實際子類的名稱(當系統復雜后,命名將是一個很不好處理的問題,為了處理可能的名字沖突,有的命名可能并不是具有很好的可讀性和可記憶性,就姑且不論不同程序員千奇百怪的個人偏好了)。
程序的擴展性和維護變得越來越困難。
◆ 2.還有一種情況就是在父類中并不知道具體要實例化哪一個具體的子類。這里的意思為:假設我們在類 A 中要使用到類 B,B 是一個抽象父類,在 A 中并不知道具體要實例化那一個 B 的子類,但是在類 A 的子類 D 中是可以知道的。在 A 中我們沒有辦法直接使用類似于 new ×××的語句,因為根本就不知道×××是什么。
以上兩個問題也就引出了工廠模式的兩個最重要的功能:
定義創建對象的接口,封裝了對象的創建;
使得具體化類的工作延遲到了子類中。
對于工廠模式,為了使其能更好的解決多種情況的問題,將其分為三類:簡單工廠模式(Simple Factory),工廠方法模式(Factory Method),抽象工廠模式(Abstract Factory)。下面來一一搞定。
具體情形:有一個肥皂廠,生產各種肥皂,有舒膚佳,夏士蓮,娜愛斯等。給這個肥皂廠建模。
UML圖如下:
對于簡單設計模式的結構圖,我們可以很清晰的看到它的組成:
1) 工廠類角色:這是本模式的核心,含有一定的商業邏輯和判斷邏輯。
2) 抽象產品角色:它一般是具體產品繼承的父類或者實現的接口。
3) 具體產品角色:工廠類所創建的對象就是此角色的實例。
簡單設計模式存在的目的很簡單:定義一個用于創建對象的接口。
缺點:對修改不封閉,新增加產品您要修改工廠。違法了鼎鼎大名的開閉法則(OCP)。
代碼實現:
#include <iostream> usingnamespace std; enum PRODUCTTYPE {SFJ,XSL,NAS}; class soapBase { public: virtual ~soapBase(){}; virtualvoid show() = 0; }; class SFJSoap:public soapBase { public: void show() {cout<<"SFJ Soap!"<<endl;} }; class XSLSoap:public soapBase { public: void show() {cout<<"XSL Soap!"<<endl;} }; class NASSoap:public soapBase { public: void show() {cout<<"NAS Soap!"<<endl;} }; class Factory { public: soapBase * creatSoap(PRODUCTTYPE type) { switch(type) { case SFJ: returnnew SFJSoap(); break; case XSL: returnnew XSLSoap(); break; case NAS: returnnew NASSoap(); break; default:break; } } }; int main() { Factory factory; soapBase* pSoap1 = factory.creatSoap(SFJ); pSoap1->show(); soapBase* pSoap2 = factory.creatSoap(XSL); pSoap2->show(); soapBase* pSoap3 = factory.creatSoap(NAS); pSoap3->show(); delete pSoap1; delete pSoap2; delete pSoap3; return 0; }
運行結果
具體情形:最近莫名肥皂需求激增!! 于是要獨立每個生產線,每個生產線只生產一種肥皂。
UML圖如下:
其實這才是真正的工廠模式,簡單工廠模式只能算是“坑爹版”的工廠模式。我們能很容易看出工廠方法模式和簡單工廠模式的區別之處。工廠方法模式的應用并不是只是為了封裝對象的創建,而是要把對象的創建放到子類中實現:Factory中只是提供了對象創建的接口,其實現將放在Factory的子類ConcreteFactory中進行。
對于工廠方法模式的組成:
1)抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。
2)具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。
3)抽象產品角色:它是具體產品繼承的父類或者是實現的接口。
4)具體產品角色:具體工廠角色所創建的對象就是此角色的實例。
缺點:每增加一種產品,就需要增加一個對象的工廠。如果這家公司發展迅速,推出了很多新的處理器核,那么就要開設相應的新工廠。在C++實現中,就是要定義一個個的工廠類。顯然,相比簡單工廠模式,工廠方法模式需要更多的類定義。
代碼實現:
#include <iostream> usingnamespace std; enum SOAPTYPE {SFJ,XSL,NAS}; class soapBase { public: virtual ~soapBase(){}; virtualvoid show() = 0; }; class SFJSoap:public soapBase { public: void show() {cout<<"SFJ Soap!"<<endl;} }; class XSLSoap:public soapBase { public: void show() {cout<<"XSL Soap!"<<endl;} }; class NASSoap:public soapBase { public: void show() {cout<<"NAS Soap!"<<endl;} }; class FactoryBase { public: virtual soapBase * creatSoap() = 0; }; class SFJFactory:public FactoryBase { public: soapBase * creatSoap() { returnnew SFJSoap(); } }; class XSLFactory:public FactoryBase { public: soapBase * creatSoap() { returnnew XSLSoap(); } }; class NASFactory:public FactoryBase { public: soapBase * creatSoap() { returnnew NASSoap(); } }; int main() { SFJFactory factory1; soapBase* pSoap1 = factory1.creatSoap(); pSoap1->show(); XSLFactory factory2; soapBase* pSoap2 = factory2.creatSoap(); pSoap2->show(); NASFactory factory3; soapBase* pSoap3 = factory3.creatSoap(); pSoap3->show(); delete pSoap1; delete pSoap2; delete pSoap3; return 0; }
運行結果
具體情形:這個肥皂廠發現搞牙膏也很賺錢,決定做牙膏。牙膏有高檔低檔,肥皂也是。現在搞兩個廠房,一個生產低檔的牙膏和肥皂,一個生產高檔的牙膏和肥皂。
比如,廠房一生產中華牙膏、娜愛斯肥皂,廠房二生產黑人牙膏和舒膚佳牙膏
UML圖如下:
對于上面的結構圖,可以看出抽象工廠模式,比前兩者更為的復雜和一般性,抽象工廠模式和工廠方法模式的區別就在于需要創建對象的復雜程度上。
抽象工廠模式:給客戶端提供一個接口,可以創建多個產品族中的產品對象 ,而且使用抽象工廠模式還要滿足一下條件:
1)系統中有多個產品族,而系統一次只可能消費其中一族產品。
2)同屬于同一個產品族的產品以其使用。
抽象工廠模式的組成(和工廠方法模式一樣):
1)抽象工廠角色:這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現的接口或者必須繼承的父類。
2)具體工廠角色:它含有和具體業務邏輯有關的代碼。由應用程序調用以創建對應的具體產品的對象。
3)抽象產品角色:它是具體產品繼承的父類或者是實現的接口。
4)具體產品角色:具體工廠角色所創建的對象就是此角色的實例。
代碼實現
#include <iostream> usingnamespace std; enum SOAPTYPE {SFJ,XSL,NAS}; enum TOOTHTYPE {HR,ZH}; class SoapBase { public: virtual ~SoapBase(){}; virtualvoid show() = 0; }; class SFJSoap:public SoapBase { public: void show() {cout<<"SFJ Soap!"<<endl;} }; class NASSoap:public SoapBase { public: void show() {cout<<"NAS Soap!"<<endl;} }; class ToothBase { public: virtual ~ToothBase(){}; virtualvoid show() = 0; }; class HRTooth:public ToothBase { public: void show() {cout<<"Hei ren Toothpaste!"<<endl;} }; class ChinaTooth:public ToothBase { public: void show() {cout<<"China Toothpaste!"<<endl;} }; class FactoryBase { public: virtual SoapBase * creatSoap() = 0; virtual ToothBase * creatToothpaste() = 0; }; class FactoryA { public: SoapBase * creatSoap() { returnnew SFJSoap(); } ToothBase * creatToothpaste() { returnnew HRTooth(); } }; class FactoryB { public: SoapBase * creatSoap() { returnnew NASSoap(); } ToothBase * creatToothpaste() { returnnew ChinaTooth(); } }; int main() { FactoryA factory1; FactoryB factory2; SoapBase *pSoap1 = NULL; ToothBase *pToothpaste1 = NULL; pSoap1 = factory1.creatSoap(); pToothpaste1 = factory1.creatToothpaste(); pSoap1->show(); pToothpaste1->show(); SoapBase *pSoap2 = NULL; ToothBase *pToothpaste2 = NULL; pSoap2 = factory2.creatSoap(); pToothpaste2 = factory2.creatToothpaste(); pSoap2->show(); pToothpaste2->show(); delete pSoap1; delete pSoap2; delete pToothpaste1; delete pToothpaste2; return 0; }
運行結果
C++設計模式 http://www.weixueyuan.net/cpp/shejimoshi/
設計模式C++實現(1)——工廠模式 - http://blog.csdn.net/wuzhekai1985/article/details/6660462
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。