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