溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

三種工廠模式的C++實(shí)現(xiàn)

發(fā)布時(shí)間:2020-10-14 21:20:19 來(lái)源:網(wǎng)絡(luò) 閱讀:4961 作者:拳四郎 欄目:關(guān)系型數(shù)據(jù)庫(kù)

引出工廠模式的設(shè)計(jì)問(wèn)題

◆ 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)一一搞定。


簡(jiǎn)單工廠

       具體情形:有一個(gè)肥皂廠,生產(chǎn)各種肥皂,有舒膚佳,夏士蓮,娜愛(ài)斯等。給這個(gè)肥皂廠建模。

       UML圖如下:

三種工廠模式的C++實(shí)現(xiàn)


對(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é)果

三種工廠模式的C++實(shí)現(xiàn)


工廠方法模式

具體情形:最近莫名肥皂需求激增!! 于是要獨(dú)立每個(gè)生產(chǎn)線,每個(gè)生產(chǎn)線只生產(chǎn)一種肥皂。

UML圖如下:

三種工廠模式的C++實(shí)現(xiàn)

       其實(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é)果


三種工廠模式的C++實(shí)現(xiàn)




抽象工廠模式

具體情形:這個(gè)肥皂廠發(fā)現(xiàn)搞牙膏也很賺錢(qián),決定做牙膏。牙膏有高檔低檔,肥皂也是?,F(xiàn)在搞兩個(gè)廠房,一個(gè)生產(chǎn)低檔的牙膏和肥皂,一個(gè)生產(chǎn)高檔的牙膏和肥皂。

比如,廠房一生產(chǎn)中華牙膏、娜愛(ài)斯肥皂,廠房二生產(chǎn)黑人牙膏和舒膚佳牙膏

UML圖如下:

三種工廠模式的C++實(shí)現(xiàn)

對(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í)現(xiàn)



參考

C++設(shè)計(jì)模式 http://www.weixueyuan.net/cpp/shejimoshi/

設(shè)計(jì)模式C++實(shí)現(xiàn)(1)——工廠模式 - http://blog.csdn.net/wuzhekai1985/article/details/6660462


向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

AI