在標準的23種設計模式中,與工廠相關的模式有2種:工廠方法模式(factory method pattern)和抽象工廠模式(abstract factory pattern)。但現在很多介紹設計模式的文章又會提到一種簡單工廠模式(****** factory pattern),甚至還有靜態工廠模式(static factory pattern),那麼這麼多種與工廠相關的模式,它們之間是個什麼關係呢?先來看圖:
簡單來說,簡單工廠是靜態工廠的公升級,抽象工廠是簡單工廠的公升級,而不管什麼工廠,它們最終都實現了工廠方法。在這裡,要區分清楚的是工廠方法模式強調的是「方法」,而抽象工廠模式強調的是「工廠」,這是兩個相關但又不相同的概念,就像「做飯」和「廚房」的區別,乙個是談動作,乙個是談空間。工廠方法是指的用工廠生產商品的方式來進行生產,而不管是簡單工廠還是抽象工廠都是在講對於工廠本身的管理。
舉個例子來說,以前你是自己做飯吃:
$food = new food();
自己乙個人做飯吃也沒什麼不好,但是因為又要做飯,又要洗衣服,事情比較多,容易亂,所以不如把做飯這件事情外包出去,我就知道我們家旁邊有乙個小飯館,去飯館買飯吃,這就是一種松耦合。為了從簡單入手,在這裡,我們假定就是幾種固定的食物,先不引入抽象商品的概念:
class staticfactory
}
好了,至此我們有了乙個靜態工廠,下面就可以點餐了:
$food = staticfactory::orderfood('chicken');
直接點餐,好簡單。
但是這樣想開乙個連鎖店,比如麥當勞這樣的,怎麼辦呢?這時候我們就需要用到簡單工廠模式:
class ******factory
}
$factory = new ******factory();
$food = $factory->orderfood();
現在我們不滿足於只吃麥當勞了,我們還想吃肯德基,反正它們都是連鎖店,提供的服務也都差不多,這時候就用到抽象工廠模式:
abstract class abstractfactory
class macdonald extends abstractfactory
}class kfc extends abstractfactory
}
抽象工廠模式有約束了,凡是成為我工廠的,你們必須提供訂餐這項基本服務。這樣,我們在點餐的時候,點麥當勞就吃到了麥當勞的食物,點肯德基就吃到了肯德基的食物。
$factory1 = new macdonald();
$food = $factory1->orderfood();
$factory2 = new kfc();
$food = $factory2->orderfood();
我們都知道麥當勞也不只賣一種食品,可能賣雞肉堡,也可能賣牛肉堡,既然要點餐,我們肯定要說明是點哪種漢堡,不可能他們給我們什麼,我們就吃什麼。你有很多種做法,我們先從最笨最簡單的開始,大部分**沿用上面的**,只是在這裡略加改動:
class macdonald extends abstractfactory
public function orderbeef(): beef
}
呼叫方法:
$factory = new macdonald();
$chicken = $factory->orderchicken();
$beef = $factory->orderbeef();
但是這樣是不是太笨了呢?我們完全可以寫成乙個方法:
class macdonald extends abstractfactory
elseif ($type == 'beef')
return $food;}}
這樣我們訂餐的時候,只要這樣就可以了:
$factory = new macdonald();
$chicken = $factory->orderfood('chicken');
$beef = $factory->orderfood('beef');
當然,為了應付很多種食物,你不應該寫if...else
而應該寫switch...case
。
最後,為了滿足依賴反轉原則(dependency inversion principle)的要求,你實際上應該把所有的商品也抽象出來:
abstract class food
class chicken extends food
class beef extends food
abstract class abstractfactory
class macdonald extends abstractfactory
elseif ($type == 'beef')
$food->brand = 'macdonald',
return $food;
}}class kfc extends abstractfactory
elseif ($type == '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();
簡單來說就是:自己不去做,交給工廠去做,這就是工廠方法模式。 工廠模式與抽象工廠模式的相關概念
工廠模式 1 定義 定義乙個建立產品物件的工廠介面,將產品物件的實際建立工作推遲到具體子工廠類當中。這滿足建立型模式中所要求的 建立與使用相分離 的特點。2 主要優點 使用者只需要知道具體工廠的名稱就可得到所要的產品,無須知道產品的具體建立過程 在系統增加新的產品時只需要新增具體產品類和對應的具體工...
設計模式之間的關係 簡單來說
總體來說設計模式分為三大類 1 建立型模式,共五種 工廠方法模式 抽象工廠模式 單例模式 建造者模式 原型模式。2 結構型模式,共七種 介面卡模式 裝飾器模式 模式 外觀模式 橋接模式 組合模式 享元模式。3 行為型模式,共十一種 策略模式 模板方法模式 觀察者模式 迭代子模式 責任鏈模式 命令模式...
設計模式 工廠類相關模式
工廠模式的定義如下 定義乙個用於建立物件的介面,讓子類決定例項化哪個類。工廠方法使乙個類的例項化延遲到其子類。其通用類圖如下。其產品類定義產品的公共屬性和介面,工廠類定義產品例項化的 方式 工廠模式 抽象工廠模式的優點 1 工廠模式巨有非常好的封裝性,結構清晰 在抽象工廠模式中,其結構還可以隨著需要...