您好,登錄后才能下訂單哦!
◆ 1.為了提高內(nèi)聚(Cohesion)和松耦合(Coupling),我們經(jīng)常會(huì)抽象出一些類(lèi)的公共接口以形成抽象基類(lèi)或者接口。這樣我們可以通過(guò)聲明一個(gè)指向基類(lèi)的指針來(lái)指向?qū)嶋H的子類(lèi)實(shí)現(xiàn),達(dá)到了多態(tài)的目的。這里很容易出現(xiàn)的一個(gè)問(wèn)題 n 多的子類(lèi)繼承自抽象基類(lèi),我們不得不在每次要用到子類(lèi)的地方就編寫(xiě)諸如 new ×××;的代碼。這里帶來(lái)兩個(gè)問(wèn)題:
客戶(hù)程序員必須知道實(shí)際子類(lèi)的名稱(chēng)(當(dāng)系統(tǒng)復(fù)雜后,命名將是一個(gè)很不好處理的問(wèn)題,為了處理可能的名字沖突,有的命名可能并不是具有很好的可讀性和可記憶性,就姑且不論不同程序員千奇百怪的個(gè)人偏好了)。
程序的擴(kuò)展性和維護(hù)變得越來(lái)越困難。
◆ 2.還有一種情況就是在父類(lèi)中并不知道具體要實(shí)例化哪一個(gè)具體的子類(lèi)。這里的意思為:假設(shè)我們?cè)陬?lèi) A 中要使用到類(lèi) B,B 是一個(gè)抽象父類(lèi),在 A 中并不知道具體要實(shí)例化那一個(gè) B 的子類(lèi),但是在類(lèi) A 的子類(lèi) D 中是可以知道的。在 A 中我們沒(méi)有辦法直接使用類(lèi)似于 new ×××的語(yǔ)句,因?yàn)楦揪筒恢馈痢痢潦鞘裁础?br />
以上兩個(gè)問(wèn)題也就引出了工廠模式的兩個(gè)最重要的功能:
定義創(chuàng)建對(duì)象的接口,封裝了對(duì)象的創(chuàng)建;
使得具體化類(lèi)的工作延遲到了子類(lèi)中。
對(duì)于工廠模式,為了使其能更好的解決多種情況的問(wèn)題,將其分為三類(lèi):簡(jiǎn)單工廠模式(Simple Factory),工廠方法模式(Factory Method),抽象工廠模式(Abstract Factory)。下面來(lái)一一搞定。
具體情形:有一個(gè)肥皂廠,生產(chǎn)各種肥皂,有舒膚佳,夏士蓮,娜愛(ài)斯等。給這個(gè)肥皂廠建模。
UML圖如下:
對(duì)于簡(jiǎn)單設(shè)計(jì)模式的結(jié)構(gòu)圖,我們可以很清晰的看到它的組成:
1) 工廠類(lèi)角色:這是本模式的核心,含有一定的商業(yè)邏輯和判斷邏輯。
2) 抽象產(chǎn)品角色:它一般是具體產(chǎn)品繼承的父類(lèi)或者實(shí)現(xiàn)的接口。
3) 具體產(chǎn)品角色:工廠類(lèi)所創(chuàng)建的對(duì)象就是此角色的實(shí)例。
簡(jiǎn)單設(shè)計(jì)模式存在的目的很簡(jiǎn)單:定義一個(gè)用于創(chuàng)建對(duì)象的接口。
缺點(diǎn):對(duì)修改不封閉,新增加產(chǎn)品您要修改工廠。違法了鼎鼎大名的開(kāi)閉法則(OCP)。
代碼實(shí)現(xiàn):
#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; }
運(yùn)行結(jié)果
具體情形:最近莫名肥皂需求激增!! 于是要獨(dú)立每個(gè)生產(chǎn)線,每個(gè)生產(chǎn)線只生產(chǎn)一種肥皂。
UML圖如下:
其實(shí)這才是真正的工廠模式,簡(jiǎn)單工廠模式只能算是“坑爹版”的工廠模式。我們能很容易看出工廠方法模式和簡(jiǎn)單工廠模式的區(qū)別之處。工廠方法模式的應(yīng)用并不是只是為了封裝對(duì)象的創(chuàng)建,而是要把對(duì)象的創(chuàng)建放到子類(lèi)中實(shí)現(xiàn):Factory中只是提供了對(duì)象創(chuàng)建的接口,其實(shí)現(xiàn)將放在Factory的子類(lèi)ConcreteFactory中進(jìn)行。
對(duì)于工廠方法模式的組成:
1)抽象工廠角色: 這是工廠方法模式的核心,它與應(yīng)用程序無(wú)關(guān)。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類(lèi)。
2)具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。
3)抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類(lèi)或者是實(shí)現(xiàn)的接口。
4)具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例。
缺點(diǎn):每增加一種產(chǎn)品,就需要增加一個(gè)對(duì)象的工廠。如果這家公司發(fā)展迅速,推出了很多新的處理器核,那么就要開(kāi)設(shè)相應(yīng)的新工廠。在C++實(shí)現(xiàn)中,就是要定義一個(gè)個(gè)的工廠類(lèi)。顯然,相比簡(jiǎn)單工廠模式,工廠方法模式需要更多的類(lèi)定義。
代碼實(shí)現(xiàn):
#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; }
運(yùn)行結(jié)果
具體情形:這個(gè)肥皂廠發(fā)現(xiàn)搞牙膏也很賺錢(qián),決定做牙膏。牙膏有高檔低檔,肥皂也是?,F(xiàn)在搞兩個(gè)廠房,一個(gè)生產(chǎn)低檔的牙膏和肥皂,一個(gè)生產(chǎn)高檔的牙膏和肥皂。
比如,廠房一生產(chǎn)中華牙膏、娜愛(ài)斯肥皂,廠房二生產(chǎn)黑人牙膏和舒膚佳牙膏
UML圖如下:
對(duì)于上面的結(jié)構(gòu)圖,可以看出抽象工廠模式,比前兩者更為的復(fù)雜和一般性,抽象工廠模式和工廠方法模式的區(qū)別就在于需要?jiǎng)?chuàng)建對(duì)象的復(fù)雜程度上。
抽象工廠模式:給客戶(hù)端提供一個(gè)接口,可以創(chuàng)建多個(gè)產(chǎn)品族中的產(chǎn)品對(duì)象 ,而且使用抽象工廠模式還要滿足一下條件:
1)系統(tǒng)中有多個(gè)產(chǎn)品族,而系統(tǒng)一次只可能消費(fèi)其中一族產(chǎn)品。
2)同屬于同一個(gè)產(chǎn)品族的產(chǎn)品以其使用。
抽象工廠模式的組成(和工廠方法模式一樣):
1)抽象工廠角色:這是工廠方法模式的核心,它與應(yīng)用程序無(wú)關(guān)。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類(lèi)。
2)具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。
3)抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類(lèi)或者是實(shí)現(xiàn)的接口。
4)具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例。
代碼實(shí)現(xiàn)
#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; }
運(yùn)行結(jié)果
C++設(shè)計(jì)模式 http://www.weixueyuan.net/cpp/shejimoshi/
設(shè)計(jì)模式C++實(shí)現(xiàn)(1)——工廠模式 - http://blog.csdn.net/wuzhekai1985/article/details/6660462
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。