意圖
為父類(lèi)聲明一個(gè)創(chuàng)建對(duì)象的方法(工廠方法)君旦,讓子類(lèi)決定創(chuàng)建哪一個(gè)類(lèi)的對(duì)象敌卓。
別名
虛構(gòu)造器(Virtual Constructor)
動(dòng)機(jī)
背景
有兩個(gè)類(lèi)千绪,Application和Document池摧,Application可以創(chuàng)建Document荔泳。
問(wèn)題
特定Application子類(lèi)創(chuàng)建特定Document子類(lèi)橙数,但是Application不知道需要?jiǎng)?chuàng)建哪個(gè)Document子類(lèi)對(duì)象尊流,所以給Application一個(gè)工廠方法(虛函數(shù))來(lái)創(chuàng)建Document子類(lèi)對(duì)象,讓Application的子類(lèi)來(lái)決定要?jiǎng)?chuàng)建哪個(gè)Document子類(lèi)的對(duì)象灯帮。
示例圖形

適用性
- 當(dāng)一個(gè)類(lèi)不知道它所創(chuàng)建的對(duì)象的類(lèi)是什么崖技,或如何創(chuàng)建的時(shí)候。
- 當(dāng)一個(gè)類(lèi)希望由它的子類(lèi)來(lái)指定它所創(chuàng)建的對(duì)象的時(shí)候钟哥。
結(jié)構(gòu)

參與者
- Product:工廠方法所要?jiǎng)?chuàng)建的產(chǎn)品的抽象類(lèi)迎献。
- ConcreteProduct:Product的具體子類(lèi)。
- Creator:聲明工廠方法(可為抽象方法)腻贰,該方法返回一個(gè)Product對(duì)象吁恍。
- ConcteteCreator:重定義工廠方法來(lái)返回ConcreteProduct實(shí)例。
協(xié)作
Creator將創(chuàng)建ConcreteProduct實(shí)例的任務(wù)延遲到ConcteteCreator。
效果
- 潛在缺點(diǎn):客戶可能僅僅為了創(chuàng)建一個(gè)特定的ConcreteProduct冀瓦,而不得不先創(chuàng)建一個(gè)ConcteteCreator伴奥。
- 用工廠方法在一個(gè)類(lèi)的內(nèi)部創(chuàng)建對(duì)象通常比直接創(chuàng)建對(duì)象更靈活。
-
連接平行的類(lèi)層次翼闽,如圖:
實(shí)現(xiàn)
- Factory Method模式有兩種情況:
- Creator工廠方法只提供聲明而不提供實(shí)現(xiàn)拾徙。
- Creator中的工廠方法提供默認(rèn)實(shí)現(xiàn)。
- 參數(shù)化工廠方法:
- 工廠方法接受一個(gè)參數(shù)肄程,通過(guò)參數(shù)得知要?jiǎng)?chuàng)建的Product類(lèi)型。
- 子類(lèi)可以重定義該工廠方法选浑,預(yù)先處理部分子類(lèi)感興趣的參數(shù)對(duì)象蓝厌,將其他參數(shù)對(duì)象延遲給父類(lèi)處理。
- 在C++中古徒,注意在Creator的構(gòu)造函數(shù)中不要調(diào)用工廠方法拓提,因?yàn)榇藭r(shí)工廠方法還沒(méi)表現(xiàn)出虛函數(shù)性質(zhì)。(詳細(xì)見(jiàn)C++單繼承相關(guān)筆記:在構(gòu)造或析構(gòu)基類(lèi)時(shí)隧膘,如果調(diào)用了某個(gè)虛函數(shù)代态,則這個(gè)虛函數(shù)使用與當(dāng)前構(gòu)造函數(shù)或析構(gòu)函數(shù)所屬類(lèi)型相對(duì)應(yīng)的虛函數(shù)版本)
-
可以配合Lazy Initialization使用來(lái)達(dá)到優(yōu)化性能和避免上述問(wèn)題的目的:
- 可以為Creator提供一個(gè)模板子類(lèi)StandardCreator,通過(guò)傳入ConcreteProduct從而避免創(chuàng)建Creator子類(lèi)疹吃。
- 命名約定:使用命名約定讓別人知道你在使用工廠方法蹦疑。如MacApp中,工廠方法的形式:Class * DoMakeClass()萨驶。
- 相關(guān)模式:
- (3.1)Abstract Factory經(jīng)常用Factory Method來(lái)實(shí)現(xiàn)歉摧。
- (5.10)Template Methods通常調(diào)用Factory Method。
- (3.4)Ptototype不需要?jiǎng)?chuàng)建Cteator的子類(lèi)腔呜,但是它們通常要一個(gè)針對(duì)Product類(lèi)的Initialize操作叁温。