C++設(shè)計(jì)模式之工廠模式
由遇到的問(wèn)題引出工廠模式
在面向?qū)ο笙到y(tǒng)設(shè)計(jì)中經(jīng)??梢杂龅揭韵碌膬深悊?wèn)題:
◆ 1.為了提高內(nèi)聚(Cohesion)和松耦合(Coupling),我們經(jīng)常會(huì)抽象出一些類的公共接口以形成抽象基類或者接口。這樣我們可以通過(guò)聲明一個(gè)指向基類的指針來(lái)指向?qū)嶋H的子類實(shí)現(xiàn),達(dá)到了多態(tài)的目的。這里很容易出現(xiàn)的一個(gè)問(wèn)題 n 多的子類繼承自抽象基類,我們不得不在每次要用到子類的地方就編寫(xiě)諸如 new ×××;的代碼。這里帶來(lái)兩個(gè)問(wèn)題:
客戶程序員必須知道實(shí)際子類的名稱(當(dāng)系統(tǒng)復(fù)雜后,命名將是一個(gè)很不好處理的問(wèn)題,為了處理可能的名字沖突,有的命名可能并不是具有很好的可讀性和可記憶性,就姑且不論不同程序員千奇百怪的個(gè)人偏好了)。
程序的擴(kuò)展性和維護(hù)變得越來(lái)越困難。
◆ 2.還有一種情況就是在父類中并不知道具體要實(shí)例化哪一個(gè)具體的子類。這里的意思為:假設(shè)我們?cè)陬?A 中要使用到類 B,B 是一個(gè)抽象父類,在 A 中并不知道具體要實(shí)例化那一個(gè) B 的子類,但是在類 A 的子類 D 中是可以知道的。在 A 中我們沒(méi)有辦法直接使用類似于 new ×××的語(yǔ)句,因?yàn)楦揪筒恢馈痢痢潦鞘裁础?/p>
以上兩個(gè)問(wèn)題也就引出了工廠模式的兩個(gè)最重要的功能:
- 定義創(chuàng)建對(duì)象的接口,封裝了對(duì)象的創(chuàng)建;
- 使得具體化類的工作延遲到了子類中。
模式選擇
我們通常使用工廠模式來(lái)解決上面給出的兩個(gè)問(wèn)題。在第一個(gè)問(wèn)題中,我們經(jīng)常就是聲明一個(gè)創(chuàng)建對(duì)象的接口,并封裝了對(duì)象的創(chuàng)建過(guò)程。工廠這里類似于一個(gè)真正意義上的工廠(生產(chǎn)對(duì)象)。在第二個(gè)問(wèn)題中,我們需要提供一個(gè)對(duì)象創(chuàng)建對(duì)象的接口,并在子類中提供其具體實(shí)現(xiàn)(因?yàn)橹挥性谧宇愔锌梢詻Q定到底實(shí)例化哪一個(gè)類)。
第一中情況的工廠的結(jié)構(gòu)示意圖為:
圖 1 所以的工廠模式經(jīng)常在系統(tǒng)開(kāi)發(fā)中用到,但是這并不是工廠模式的最大威力所在(因?yàn)檫@可以通過(guò)其他方式解決這個(gè)問(wèn)題)。工廠模式不單是提供了創(chuàng)建對(duì)象的接口,其最重要的是延遲了子類的實(shí)例化(第二個(gè)問(wèn)題),以下是這種情況的一個(gè)工廠的結(jié)構(gòu)示意圖:
圖 2 中關(guān)鍵中工廠模式的應(yīng)用并不是只是為了封裝對(duì)象的創(chuàng)建,而是要把對(duì)象的創(chuàng)建放到子類中實(shí)現(xiàn):工廠中只是提供了對(duì)象創(chuàng)建的接口,其實(shí)現(xiàn)將放在工廠的子類Concrete工廠中進(jìn)行。這是圖 2 和圖 1 的區(qū)別所在。
工廠模式的實(shí)現(xiàn)
完整代碼示例(code):工廠模式的實(shí)現(xiàn)比較簡(jiǎn)單,這里為了方便初學(xué)者的學(xué)習(xí)和參考,將給出完整的實(shí)現(xiàn)代碼(所有代碼采用 C++實(shí)現(xiàn),并在 VC 6.0 下測(cè)試運(yùn)行)。
代碼片斷 1:Product.h
//Product.h #ifndef _PRODUCT_H_ #define _PRODUCT_H_ class Product{ public: virtual ~Product() =0; protected: Product(); //屏蔽構(gòu)造函數(shù) private: }; class ConcreteProduct:publicProduct{ public: ~ConcreteProduct(); ConcreteProduct(); protected: private: }; #endif //~_PRODUCT_H_
代碼片斷 2:Product.cpp
//Product.cpp #include "Product.h" #include<iostream> using namespace std; Product::Product(){ } Product::~Product(){ } ConcreteProduct::ConcreteProduct(){ cout<<"ConcreteProduct...."<<endl; } ConcreteProduct::~ConcreteProduct(){ }
代碼片斷 3:Factory.h
//Factory.h #ifndef _FACTORY_H_ #define _FACTORY_H_ class Product; class Factory{ public: virtual ~Factory() = 0; virtual Product* CreateProduct() = 0; protected: Factory(); private: }; class ConcreteFactory:public Factory{ public: ~ConcreteFactory(); ConcreteFactory(); Product* CreateProduct(); protected: private: }; #endif //~_FACTORY_H_
代碼片斷 4:Factory.cpp
//Factory.cpp #include "Factory.h" #include "Product.h" #include <iostream> using namespace std; Factory::Factory(){ } Factory::~Factory(){ } ConcreteFactory::ConcreteFactory(){ cout<<"ConcreteFactory....."<<endl; } ConcreteFactory::~ConcreteFactory(){ } Product* ConcreteFactory::CreateProduct(){ return new ConcreteProduct(); }
代碼片斷 5:main.cpp
//main.cpp #include "Factory.h" #include "Product.h" #include <iostream> using namespace std; int main(int argc,char* argv[]){ Factory* fac = new ConcreteFactory(); Product* p = fac->CreateProduct(); return 0; }
代碼說(shuō)明:示例代碼中給出的是工廠模式解決父類中并不知道具體要實(shí)例化哪一個(gè)具體的子類的問(wèn)題,至于為創(chuàng)建對(duì)象提供接口問(wèn)題,可以由工廠中附加相應(yīng)的創(chuàng)建操作例如Create***Product()即可。具體請(qǐng)參加討論內(nèi)容。
關(guān)于工廠模式的討論
工廠模式在實(shí)際開(kāi)發(fā)中應(yīng)用非常廣泛,面向?qū)ο蟮南到y(tǒng)經(jīng)常面臨著對(duì)象創(chuàng)建問(wèn)題:要?jiǎng)?chuàng)建的類實(shí)在是太多了。而工廠提供的創(chuàng)建對(duì)象的接口封裝(第一個(gè)功能),以及其將類的實(shí)例化推遲到子類(第二個(gè)功能)都部分地解決了實(shí)際問(wèn)題。一個(gè)簡(jiǎn)單的例子就是筆者開(kāi)開(kāi)發(fā) VisualCMCS 系統(tǒng)的語(yǔ)義分析過(guò)程中,由于要為文法中的每個(gè)非終結(jié)符構(gòu)造一個(gè)類處理,因此這個(gè)過(guò)程中對(duì)象的創(chuàng)建非常多,采用工廠模式后系統(tǒng)可讀性性和維護(hù)都變得elegant 許多。
工廠模式也帶來(lái)至少以下兩個(gè)問(wèn)題:
- 如果為每一個(gè)具體的 ConcreteProduct 類的實(shí)例化提供一個(gè)函數(shù)體,那么我們可能不得不在系統(tǒng)中添加了一個(gè)方法來(lái)處理這個(gè)新建的 ConcreteProduct,這樣工廠的接口永遠(yuǎn)就不肯能封閉(Close)。當(dāng)然我們可以通過(guò)創(chuàng)建一個(gè)工廠的子類來(lái)通過(guò)多態(tài)實(shí)現(xiàn)這一點(diǎn),但是這也是以新建一個(gè)類作為代價(jià)的。
- 在實(shí)現(xiàn)中我們可以通過(guò)參數(shù)化工廠方法,即給 工廠Method()傳遞一個(gè)參數(shù)用以決定是創(chuàng)建具體哪一個(gè)具體的 Product(實(shí)際上筆者在 VisualCMCS 中也正是這樣做的)。當(dāng)然也可以通過(guò)模板化避免 1)中的子類創(chuàng)建子類,其方法就是將具體 Product 類作為模板參數(shù),實(shí)現(xiàn)起來(lái)也很簡(jiǎn)單。
可以看出,工廠模式對(duì)于對(duì)象的創(chuàng)建給予開(kāi)發(fā)人員提供了很好的實(shí)現(xiàn)策略,但是工廠模式僅僅局限于一類類(就是說(shuō) Product 是一類,有一個(gè)共同的基類),如果我們要為不同類的類提供一個(gè)對(duì)象創(chuàng)建的接口,那就要用 Abstract工廠了。
上一篇:C++回文數(shù)及素?cái)?shù)問(wèn)題計(jì)算方法
欄 目:C語(yǔ)言
下一篇:C語(yǔ)言練習(xí)題:求1到10的階乘之和簡(jiǎn)單實(shí)例
本文標(biāo)題:C++設(shè)計(jì)模式之工廠模式
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/2295.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 01-10深入理解C++中常見(jiàn)的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10APUE筆記之:進(jìn)程環(huán)境詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置