摘要:在標(biāo)準(zhǔn)的種設(shè)計(jì)模式中,與工廠相關(guān)的模式有種工廠方法模式和抽象工廠模式。在這里,要區(qū)分清楚的是工廠方法模式強(qiáng)調(diào)的是方法,而抽象工廠模式強(qiáng)調(diào)的是工廠,這是兩個(gè)相關(guān)但又不相同的概念,就像做飯和廚房的區(qū)別,一個(gè)是談動(dòng)作,一個(gè)是談空間。
在標(biāo)準(zhǔn)的23種設(shè)計(jì)模式中,與工廠相關(guān)的模式有2種:工廠方法模式(Factory method pattern)和抽象工廠模式(Abstract factory pattern)。但現(xiàn)在很多介紹設(shè)計(jì)模式的文章又會(huì)提到一種簡(jiǎn)單工廠模式(Simple factory pattern),甚至還有靜態(tài)工廠模式(Static factory pattern),那么這么多種與工廠相關(guān)的模式,它們之間是個(gè)什么關(guān)系呢?先來(lái)看圖:
簡(jiǎn)單來(lái)說(shuō),簡(jiǎn)單工廠是靜態(tài)工廠的升級(jí),抽象工廠是簡(jiǎn)單工廠的升級(jí),而不管什么工廠,它們最終都實(shí)現(xiàn)了工廠方法。在這里,要區(qū)分清楚的是工廠方法模式強(qiáng)調(diào)的是“方法”,而抽象工廠模式強(qiáng)調(diào)的是“工廠”,這是兩個(gè)相關(guān)但又不相同的概念,就像“做飯”和“廚房”的區(qū)別,一個(gè)是談動(dòng)作,一個(gè)是談空間。工廠方法是指的用工廠生產(chǎn)商品的方式來(lái)進(jìn)行生產(chǎn),而不管是簡(jiǎn)單工廠還是抽象工廠都是在講對(duì)于工廠本身的管理。
沒(méi)有工廠模式舉個(gè)例子來(lái)說(shuō),以前你是自己做飯吃:
$food = new Food();靜態(tài)工廠模式
自己一個(gè)人做飯吃也沒(méi)什么不好,但是因?yàn)橛忠鲲垼忠匆路?,事情比較多,容易亂,所以不如把做飯這件事情外包出去,我就知道我們家旁邊有一個(gè)小飯館,去飯館買(mǎi)飯吃,這就是一種松耦合。為了從簡(jiǎn)單入手,在這里,我們假定就是幾種固定的食物,先不引入抽象商品的概念:
class StaticFactory { public static function orderFood(): Food { return new Food(); } }
好了,至此我們有了一個(gè)靜態(tài)工廠,下面就可以點(diǎn)餐了:
$food = StaticFactory::orderFood("chicken");
直接點(diǎn)餐,好簡(jiǎn)單。
簡(jiǎn)單工廠模式但是這樣想開(kāi)一個(gè)連鎖店,比如麥當(dāng)勞這樣的,怎么辦呢?這時(shí)候我們就需要用到簡(jiǎn)單工廠模式:
class SimpleFactory { public function orderFood(): Food { return new Food(); } }
和上面的方法幾乎沒(méi)有任何差別,唯一的差別只是少了一個(gè)static關(guān)鍵詞,這樣我們?cè)邳c(diǎn)餐時(shí),就需要先新建一個(gè)工廠,然后再點(diǎn)餐,這就是簡(jiǎn)單工廠:
$factory = new SimpleFactory(); $food = $factory->orderFood();抽象工廠模式
現(xiàn)在我們不滿(mǎn)足于只吃麥當(dāng)勞了,我們還想吃肯德基,反正它們都是連鎖店,提供的服務(wù)也都差不多,這時(shí)候就用到抽象工廠模式:
abstract class AbstractFactory { abstract public function orderFood(): Food; } class MacDonald extends AbstractFactory { public function orderFood(): Food { $food = new Food(); $food->brand = "MacDonald"; return $food; } } class KFC extends AbstractFactory { public function orderFood(): Food { $food = new Food(); $food->brand = "KFC"; return $food; } }
抽象工廠模式有約束了,凡是成為我工廠的,你們必須提供訂餐這項(xiàng)基本服務(wù)。這樣,我們?cè)邳c(diǎn)餐的時(shí)候,點(diǎn)麥當(dāng)勞就吃到了麥當(dāng)勞的食物,點(diǎn)肯德基就吃到了肯德基的食物。
$factory1 = new MacDonald(); $food = $factory1->orderFood(); $factory2 = new KFC(); $food = $factory2->orderFood();簡(jiǎn)單商品
我們都知道麥當(dāng)勞也不只賣(mài)一種食品,可能賣(mài)雞肉堡,也可能賣(mài)牛肉堡,既然要點(diǎn)餐,我們肯定要說(shuō)明是點(diǎn)哪種漢堡,不可能他們給我們什么,我們就吃什么。你有很多種做法,我們先從最笨最簡(jiǎn)單的開(kāi)始,大部分代碼沿用上面的代碼,只是在這里略加改動(dòng):
class MacDonald extends AbstractFactory { public function orderChicken(): Chicken { $food = new Chicken(); return $food; } public function orderBeef(): Beef { $food = new Beef(); return $food; } }
調(diào)用方法:
$factory = new MacDonald(); $chicken = $factory->orderChicken(); $beef = $factory->orderBeef();換一種寫(xiě)法
但是這樣是不是太笨了呢?我們完全可以寫(xiě)成一個(gè)方法:
class MacDonald extends AbstractFactory { public function orderFood($type) { if ($type == "chicken") { $food = new Chicken(); } elseif ($type == "beef") { $food = new Beef(); } return $food; } }
這樣我們訂餐的時(shí)候,只要這樣就可以了:
$factory = new MacDonald(); $chicken = $factory->orderFood("chicken"); $beef = $factory->orderFood("beef");
當(dāng)然,為了應(yīng)付很多種食物,你不應(yīng)該寫(xiě)if...else而應(yīng)該寫(xiě)switch...case。
抽象商品最后,為了滿(mǎn)足依賴(lài)反轉(zhuǎn)原則(Dependency inversion principle)的要求,你實(shí)際上應(yīng)該把所有的商品也抽象出來(lái):
abstract class Food { public $brand; } class Chicken extends Food { } class Beef extends Food { } abstract class AbstractFactory { abstract public function orderFood(): Food; } class MacDonald extends AbstractFactory { public function orderFood($type): Food { if ($type == "chicken") { $food = new Chicken(); } elseif ($type == "beef") { $food = new Beef(); } $food->brand = "MacDonald", return $food; } } class KFC extends AbstractFactory { public function orderFood($type): Food { if ($type == "chicken") { $food = new Chicken(); } elseif ($type == "beef") { $food = new Beef(); } $food->brand = "KFC", return $food; } } $factory1 = new MacDonald(); $chicken1 = $factory1->orderFood("chicken"); $beef1 = $factory1->orderFood("beef"); $factory2 = new KFC(); $chicken2 = $factory2->orderFood("chicken"); $beef2 = $factory2->orderFood("beef");
同樣還是那個(gè)雞肉,同樣還是那個(gè)牛肉,但是我們吃到了不同廠家的不同的食物。這就是抽象工廠+抽象商品的作用,最終你達(dá)到了完全解耦的目的。
工廠方法模式說(shuō)了這么半天,工廠方法模式在哪里?工廠方法模式其實(shí)已經(jīng)完全溶化在每一個(gè)工廠當(dāng)中,即使是最簡(jiǎn)單的靜態(tài)工廠,只此一句話(huà),就已經(jīng)說(shuō)明它在用工廠模式了:
return new Food();
簡(jiǎn)單來(lái)說(shuō)就是:自己不去做,交給工廠去做,這就是工廠方法模式。
我這里講的只是一個(gè)入門(mén),希望初學(xué)者不要上來(lái)就被那些高大上的名詞砸暈,嚇的不敢問(wèn)津了。其實(shí)設(shè)計(jì)模式?jīng)]那么復(fù)雜,沒(méi)什么高大上的,只要理解了它們的本質(zhì),誰(shuí)都可以輕松掌握,人人可以成為架構(gòu)師。當(dāng)然,更高深的理解還需要你去仔細(xì)鉆研,也歡迎大家提出不同見(jiàn)解,共同學(xué)習(xí),共同提高。在這里,我推薦一下這個(gè)鏈接,在這里你可以更加詳細(xì)地了解其他模式。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/23314.html
摘要:抽象工廠模式將具有共同主題的對(duì)象工廠分組。對(duì)可重用性和可維護(hù)性設(shè)計(jì)模式的高層考慮創(chuàng)造性模式工廠方法模式也稱(chēng)為虛擬構(gòu)造器意圖定義一個(gè)用于創(chuàng)建對(duì)象的接口,但讓子類(lèi)決定實(shí)例化哪個(gè)類(lèi)。 大綱 創(chuàng)造性模式 工廠方法模式創(chuàng)建對(duì)象而不指定要?jiǎng)?chuàng)建的確切類(lèi)。 抽象工廠模式將具有共同主題的對(duì)象工廠分組。 Builder模式通過(guò)分離構(gòu)造和表示來(lái)構(gòu)造復(fù)雜的對(duì)象。 結(jié)構(gòu)模式 Bridge將抽象從其實(shí)現(xiàn)中分...
摘要:抽象工廠模式是為了處理對(duì)象具有等級(jí)結(jié)構(gòu)以及對(duì)象族的問(wèn)題。單例設(shè)計(jì)模式單例模式確保某一個(gè)類(lèi)只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,這個(gè)類(lèi)成為單例類(lèi)。 導(dǎo)語(yǔ):設(shè)計(jì)模式是無(wú)數(shù)碼農(nóng)前人在實(shí)際的生產(chǎn)項(xiàng)目中經(jīng)過(guò)不斷的踩坑、爬坑、修坑的經(jīng)歷總結(jié)出來(lái)的經(jīng)驗(yàn)教訓(xùn),經(jīng)過(guò)抽象之后表達(dá)成的概念。能夠幫助后來(lái)的設(shè)計(jì)者避免重復(fù)同樣的錯(cuò)誤或者彎路。我也抽空整理了一下設(shè)計(jì)模式,用自己的話(huà)總結(jié)了一下,自認(rèn)...
摘要:設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案。設(shè)計(jì)模式的類(lèi)型共有種設(shè)計(jì)模式。工廠模式工廠模式最常用的設(shè)計(jì)模式之一。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。 該文建議配合 design-patterns-for-humans 中文版 一起看。 推薦閱讀 超全的設(shè)計(jì)模式簡(jiǎn)介(45種) design-patterns-for-humans 中文版...
摘要:設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案。設(shè)計(jì)模式的類(lèi)型共有種設(shè)計(jì)模式。工廠模式工廠模式最常用的設(shè)計(jì)模式之一。這種類(lèi)型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。 該文建議配合 design-patterns-for-humans 中文版 一起看。 推薦閱讀 超全的設(shè)計(jì)模式簡(jiǎn)介(45種) design-patterns-for-humans 中文版...
摘要:原文鏈接常用設(shè)計(jì)模式設(shè)計(jì)模式設(shè)計(jì)模式是一種在長(zhǎng)時(shí)間的經(jīng)驗(yàn)與錯(cuò)誤中總結(jié)出來(lái)可服用的解決方案。用來(lái)模擬接口的相關(guān)操作我很帥通過(guò)適配器函數(shù)來(lái)調(diào)用目的我很帥學(xué)習(xí)資料聽(tīng)飛狐聊設(shè)計(jì)模式系列設(shè)計(jì)模式湯姆大叔 原文鏈接: JavaScript常用設(shè)計(jì)模式 設(shè)計(jì)模式 設(shè)計(jì)模式是一種在長(zhǎng)時(shí)間的經(jīng)驗(yàn)與錯(cuò)誤中總結(jié)出來(lái)可服用的解決方案。 設(shè)計(jì)模式主要分為3類(lèi): 創(chuàng)建型設(shè)計(jì)模式:專(zhuān)注于處理對(duì)象的創(chuàng)建 Const...
閱讀 3888·2021-09-10 11:22
閱讀 2360·2021-09-03 10:30
閱讀 3675·2019-08-30 15:55
閱讀 1912·2019-08-30 15:44
閱讀 853·2019-08-30 15:44
閱讀 598·2019-08-30 14:04
閱讀 3052·2019-08-29 17:18
閱讀 1276·2019-08-29 15:04