設(shè)計模式[創(chuàng)建型]02--工廠方法模式(Factory)

一奕锌、簡介

工廠方法模式(Factory Method Pattern)又稱為 工廠模式,也叫虛擬構(gòu)造器(Virtual Constructor)模式或者多態(tài)工廠(Polymorphic Factory)模式,它屬于類創(chuàng)建型模式桦他。在工廠方法模式中茬暇,工廠父類負責定義創(chuàng)建產(chǎn)品對象的公共接口,而工廠子類則負責生成具體的產(chǎn)品對象敢课,這樣做的目的是將產(chǎn)品類的實例化操作延遲到工廠子類中完成阶祭,即通過工廠子類來確定究竟應該實例化哪一個具體產(chǎn)品類。為系統(tǒng)結(jié)構(gòu)提供靈活的動態(tài)擴展機制直秆,減少了耦合濒募。

根據(jù)抽象程度的不同,工廠模式可化分為三種:

  • 簡單工廠模式
  • 工廠方法模式
  • 抽象工廠模式

二圾结、原理

在簡單工廠模式中只提供一個工廠類瑰剃,該工廠類處于對產(chǎn)品類進行實例化的中心位置,它需要知道每一個產(chǎn)品對象的創(chuàng)建細節(jié)筝野,并決定何時實例化哪一個產(chǎn)品類晌姚。簡單工廠模式最大的缺點是當有新產(chǎn)品要加入到系統(tǒng)中時,必須修改工廠類遗座,需要在其中加入必要的業(yè)務(wù)邏輯舀凛,這違背了“開閉原則”。此外途蒋,在簡單工廠模式中猛遍,所有的產(chǎn)品都由同一個工廠創(chuàng)建,工廠類職責較重号坡,業(yè)務(wù)邏輯較為復雜懊烤,具體產(chǎn)品與工廠類之間的耦合度高,嚴重影響了系統(tǒng)的靈活性和擴展性宽堆,而工廠方法模式則可以很好地解決這一問題腌紧。

在工廠方法模式中,我們不再提供一個統(tǒng)一的工廠類來創(chuàng)建所有的產(chǎn)品對象畜隶,而是針對不同的產(chǎn)品提供不同的工廠壁肋,系統(tǒng)提供一個與產(chǎn)品等級結(jié)構(gòu)對應的工廠等級結(jié)構(gòu)号胚。工廠方法模式定義如下:

工廠方法模式(Factory Method Pattern):定義一個用于創(chuàng)建對象的接口,讓子類決定將哪一個類實例化浸遗。工廠方法模式讓一個類的實例化延遲到其子類猫胁。工廠方法模式又簡稱為工廠模式(Factory Pattern),又可稱作虛擬構(gòu)造器模式(Virtual Constructor Pattern)或多態(tài)工廠模式(Polymorphic Factory Pattern)跛锌。工廠方法模式是一種類創(chuàng)建型模式弃秆。

工廠方法模式提供一個抽象工廠接口來聲明抽象工廠方法,而由其子類來具體實現(xiàn)工廠方法髓帽,創(chuàng)建具體的產(chǎn)品對象菠赚。工廠方法模式結(jié)構(gòu)如圖2所示:

三、類結(jié)構(gòu)

工廠方法模式定義一個用于創(chuàng)建對象的接口郑藏,讓子類決定哪個類實例化衡查。 他可以解決簡單工廠模式中的封閉開放原則問題。

與簡單工廠模式相比必盖,工廠方法模式最重要的區(qū)別是引入了抽象工廠角色峡捡,抽象工廠可以是接口,也可以是抽象類或者具體類筑悴。

結(jié)構(gòu)如下:

角色 類別 簡述
Product 產(chǎn)品類 一般是一個抽象類或是接口
ConcreteProduct 具體的產(chǎn)品類 實現(xiàn)或是繼承 Product
Factory 工廠類 抽象工廠
ConcreteFactory 具體的工廠類 實現(xiàn)或是繼承Factory
  • Product(抽象產(chǎn)品):它是定義產(chǎn)品的接口们拙,是工廠方法模式所創(chuàng)建對象的超類型,也就是產(chǎn)品對象的公共父類阁吝。
  • ConcreteProduct(具體產(chǎn)品):它實現(xiàn)了抽象產(chǎn)品接口砚婆,某種類型的具體產(chǎn)品由專門的具體工廠創(chuàng)建,具體工廠和具體產(chǎn)品之間一一對應突勇。
  • Factory(抽象工廠):在抽象工廠類中装盯,聲明了工廠方法(Factory Method),用于返回一個產(chǎn)品甲馋。抽象工廠是工廠方法模式的核心埂奈,所有創(chuàng)建對象的工廠類都必須實現(xiàn)該接口。
  • ConcreteFactory(具體工廠):它是抽象工廠類的子類定躏,實現(xiàn)了抽象工廠中定義的工廠方法账磺,并可由客戶端調(diào)用,返回一個具體產(chǎn)品類的實例痊远。

四垮抗、UML圖

五、代碼分析

比如碧聪,我們需要設(shè)計一個日志記錄器:

1冒版、抽象產(chǎn)品類

//日志記錄器接口:抽象產(chǎn)品  
interface Logger {  
    public function writeLog();  
}  

2、具體產(chǎn)品類

//1)數(shù)據(jù)庫日志記錄器:具體產(chǎn)品  
class DatabaseLogger implements Logger {  
    public function writeLog() {  
        echo "數(shù)據(jù)庫日志記錄逞姿。"; 
    }  
}  

//2)文件日志記錄器:具體產(chǎn)品  
class FileLogger implements Logger {  
    public function writeLog() {  
        echo "文件日志記錄辞嗡。";  
    }  
}  

3捆等、抽象工廠類

//日志記錄器工廠接口:抽象工廠  
interface LoggerFactory {  
    public function createLogger();  
}  

4、具體工廠類
在實際使用時续室,具體工廠類在實現(xiàn)工廠方法時除了創(chuàng)建具體產(chǎn)品對象之外楚里,還可以負責產(chǎn)品對象的初始化工作以及一些資源和環(huán)境配置工作,例如連接數(shù)據(jù)庫猎贴、創(chuàng)建文件等。

//1)數(shù)據(jù)庫日志記錄器工廠類:具體工廠  
class DatabaseLoggerFactory implements LoggerFactory {  
    public function createLogger() {  
            //連接數(shù)據(jù)庫蝴光,代碼省略  
            //創(chuàng)建數(shù)據(jù)庫日志記錄器對象  
            $logger = new DatabaseLogger();   
            //初始化數(shù)據(jù)庫日志記錄器她渴,代碼省略  
            return $logger; 
    }     
}  

//2)文件日志記錄器工廠類:具體工廠  
class FileLoggerFactory implements LoggerFactory {  
    public function createLogger() {  
            //創(chuàng)建文件日志記錄器對象  
            $logger = new FileLogger();   
            //創(chuàng)建文件,代碼省略  
            return $logger;  
    }     
}

5蔑祟、例子

$file_factory = new FileLoggerFactory(); //可引入配置文件實現(xiàn)  
$file_logger = factory->createLogger();  
$file_logger->writeLog(); 

$db_lfactory = new DatabaseLoggerFactory(); //可引入配置文件實現(xiàn)
$db_logger = factory->createLogger();  
$db_logger->writeLog(); 

輸出結(jié)果如下:

文件日志記錄趁耗。
數(shù)據(jù)庫日志記錄。

六疆虚、特點

工廠方法模式是簡單工廠模式的延伸苛败,它繼承了簡單工廠模式的優(yōu)點,同時還彌補了簡單工廠模式的不足径簿。工廠方法模式是使用頻率最高的設(shè)計模式之一罢屈,是很多開源框架和API類庫的核心模式。

1篇亭、 優(yōu)點

  • 在工廠方法模式中缠捌,工廠方法用來創(chuàng)建客戶所需要的產(chǎn)品,同時還向客戶隱藏了哪種具體產(chǎn)品類將被實例化這一細節(jié)译蒂,用戶只需要關(guān)心所需產(chǎn)品對應的工廠曼月,無須關(guān)心創(chuàng)建細節(jié),甚至無須知道具體產(chǎn)品類的類名柔昼。
  • 基于工廠角色和產(chǎn)品角色的多態(tài)性設(shè)計是工廠方法模式的關(guān)鍵哑芹。它能夠讓工廠可以自主確定創(chuàng)建各種產(chǎn)品對象,而如何創(chuàng)建這個對象的細節(jié)則完全封裝在具體工廠內(nèi)部捕透。工廠方法模式之所以又被稱為多態(tài)工廠模式聪姿,就正是因為所有的具體工廠類都具有同一抽象父類。
  • 使用工廠方法模式的另一個優(yōu)點是在系統(tǒng)中加入新產(chǎn)品時乙嘀,無須修改抽象工廠和抽象產(chǎn)品提供的接口咳燕,無須修改客戶端,也無須修改其他的具體工廠和具體產(chǎn)品乒躺,而只要添加一個具體工廠和具體產(chǎn)品就可以了招盲,這樣,系統(tǒng)的可擴展性也就變得非常好嘉冒,完全符合“開閉原則”曹货。

2咆繁、 缺點

  • 在添加新產(chǎn)品時,需要編寫新的具體產(chǎn)品類顶籽,而且還要提供與之對應的具體工廠類玩般,系統(tǒng)中類的個數(shù)將成對增加,在一定程度上增加了系統(tǒng)的復雜度礼饱,有更多的類需要編譯和運行坏为,會給系統(tǒng)帶來一些額外的開銷。
  • 由于考慮到系統(tǒng)的可擴展性镊绪,需要引入抽象層匀伏,在客戶端代碼中均使用抽象層進行定義,增加了系統(tǒng)的抽象性和理解難度蝴韭,且在實現(xiàn)時可能需要用到DOM够颠、反射等技術(shù),增加了系統(tǒng)的實現(xiàn)難度榄鉴。

3履磨、 適用場景

滿足以下條件時,可以考慮使用工廠模式方法:

  • 一個類不知道它所需要的對象的類:在工廠方法模式中庆尘,客戶端不需要知道具體產(chǎn)品類的類名剃诅,只需要知道所對應的工廠即可,具體的產(chǎn)品對象由具體工廠類創(chuàng)建驶忌;客戶端需要知道創(chuàng)建具體產(chǎn)品的工廠類综苔。
  • 一個類通過其子類來指定創(chuàng)建哪個對象:在工廠方法模式中,對于抽象工廠類只需要提供一個創(chuàng)建產(chǎn)品的接口位岔,而由其子類來確定具體要創(chuàng)建的對象如筛,利用面向?qū)ο蟮亩鄳B(tài)性和里氏代換原則,在程序運行時抒抬,子類對象將覆蓋父類對象杨刨,從而使得系統(tǒng)更容易擴展。
  • 將創(chuàng)建對象的任務(wù)委托給多個工廠子類中的某一個擦剑,客戶端在使用時可以無須關(guān)心是哪一個工廠子類創(chuàng)建產(chǎn)品子類妖胀,需要時再動態(tài)指定,可將具體工廠類的類名存儲在配置文件或數(shù)據(jù)庫中惠勒。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末赚抡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子纠屋,更是在濱河造成了極大的恐慌涂臣,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赁遗,居然都是意外死亡署辉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門岩四,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哭尝,“玉大人,你說我怎么就攤上這事剖煌〔酿校” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵耕姊,是天一觀的道長桶唐。 經(jīng)常有香客問我,道長箩做,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任妥畏,我火速辦了婚禮邦邦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘醉蚁。我一直安慰自己燃辖,他們只是感情好,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布网棍。 她就那樣靜靜地躺著黔龟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪滥玷。 梳的紋絲不亂的頭發(fā)上氏身,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音惑畴,去河邊找鬼蛋欣。 笑死,一個胖子當著我的面吹牛如贷,可吹牛的內(nèi)容都是我干的陷虎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼杠袱,長吁一口氣:“原來是場噩夢啊……” “哼尚猿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起楣富,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤凿掂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后纹蝴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缠劝,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡潮梯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了惨恭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秉馏。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖脱羡,靈堂內(nèi)的尸體忽然破棺而出萝究,到底是詐尸還是另有隱情,我是刑警寧澤锉罐,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布帆竹,位于F島的核電站,受9級特大地震影響脓规,放射性物質(zhì)發(fā)生泄漏栽连。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一侨舆、第九天 我趴在偏房一處隱蔽的房頂上張望秒紧。 院中可真熱鬧,春花似錦挨下、人聲如沸熔恢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叙淌。三九已至,卻和暖如春愁铺,著一層夾襖步出監(jiān)牢的瞬間鹰霍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工茵乱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衅谷,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓似将,卻偏偏與公主長得像获黔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子在验,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容

  • 【學習難度:★★☆☆☆玷氏,使用頻率:★★★★★】直接出處:工廠方法模式梳理和學習:https://github.co...
    BruceOuyang閱讀 617評論 0 2
  • 簡單工廠模式雖然簡單,但存在一個很嚴重的問題腋舌。當系統(tǒng)中需要引入新產(chǎn)品時盏触,由于靜態(tài)工廠方法通過所傳入?yún)?shù)的不同來創(chuàng)建...
    justCode_閱讀 1,190評論 1 9
  • 一、工廠模式介紹 工廠模式專門負責將大量有共同接口的類實例化。工廠模式可以動態(tài)決定將哪一個類實例化赞辩,不必事先知道每...
    QuantRuu閱讀 759評論 0 51
  • 工廠模式是我們最常用的實例化對象模式了雌芽,是用工廠方法代替new操作的一種模式。通常我們所說的工廠模式是指工廠方法模...
    zfylin閱讀 1,319評論 0 7
  • 今天上午寫完作業(yè)和小朋友做游戲下午和媽媽一起參加的抓魚游戲最高興的是我抓到了一天大魚可開心了
    李晨一哲閱讀 185評論 0 0