聲明:本系列部落格參考資料《大話設計模式》,作者程傑。
前面我們介紹了簡單工廠和Factory 方法設計模式,今天我們學習最後一個工廠??抽象工廠。
案例:追MM少不了請吃飯了,去麥當勞,只管向服務員說“兩個B套餐”就行了。麥當勞就是B套餐的AbstractFactory,B套餐裡含有漢堡, 雞翅和飲料. 麥當勞或肯德基會根據B套餐的規格, 讓漢堡Factory, 雞翅Factory,飲料Factory分別生產對應B套餐的材料.
抽象原廠模式:提供一個建立一系列相關或相互依賴對象的介面,而無需指定它們具體的類。客戶類和工廠類分開。消費者任何時候需要某套產品集合時,只需向抽象工廠請求即可。抽象工廠會再向具體的工廠生產出符合產品集規格的產品.
UML類圖實現:
UML類圖代碼實現:
"; }}/**具體產品角色 雞肉漢堡 * Class ChickenHamb */class ChickenHamb implements IAllayFood{ function Allay() { echo "雞肉漢堡充饑了。。。。。。。
"; }}/**具體產品角色 可口可樂 * Class KekouKele */class KekouKele implements IDrinkFood{ function Drink() { echo "可口可樂解渴了。。。。。。。。。
"; }}/**具體產品角色 百事可樂 * Class BaishiKele */class BaishiKele implements IDrinkFood{ function Drink() { echo "百事可樂解渴了。。。。。。。。
"; }}//-------------------抽象工廠---------------------/**頂層超級抽象工廠介面 * Interface IFactory */interface IFactory{ //得到充饑食物 function GetAllayFood(); //得到解渴食物 function GetDrinkFood();}/**工廠A A套餐:蝦仁漢堡+百事可樂 * Class IAFactory */class AFactory implements IFactory{ function GetAllayFood() { return new XiaRenHamb(); } function GetDrinkFood() { return new BaishiKele(); }}/**工廠B B套餐:雞肉漢堡+可口可樂 * Class IBFactory */class BFactory implements IFactory{ function GetAllayFood() { return new ChickenHamb(); } function GetDrinkFood() { return new KekouKele(); }}
用戶端測試代碼
header("Content-Type:text/html;charset=utf-8");//------------------------抽象工廠測試代碼------------------require_once "./AbstractFactory/AbstractFactory.php";//------------------點套餐-------------$factoryA=new AFactory();$factoryB=new BFactory();//------------------麥當勞製作套餐食物------------//A套餐$allayA=$factoryA->GetAllayFood();$drinkA=$factoryA->GetDrinkFood();//B套餐$allayB=$factoryB->GetAllayFood();$drinkB=$factoryB->GetDrinkFood();//-------------------享受套餐---------------echo "享受A套餐:
";$allayA->Allay();$drinkA->Drink();echo "享受B套餐:
";$allayB->Allay();$drinkB->Drink();
當每個抽象產品都有多於一個的具體子類的時候,工廠角色怎麼知道執行個體化哪一個子類呢?比如每個抽象產品角色都有兩個具體產品。抽象原廠模式提供兩個具體工廠角色,分別對應於這兩個具體產品角色,每一個具體工廠角色只負責某一個產品角色的執行個體化。每一個具體工廠類只負責建立抽象產品的某一個具體子類的執行個體。
適用情境:
1、遊戲開發中的多風格系列情境(套餐),比如道路(介面),房屋,管道等。
2、系統要在三個不同平台上運行,比如Windows、Linux、Android上運行,你會怎麼設計?通過抽象原廠模式屏蔽掉作業系統對應用的影響。三個不同作業系統上的軟體功能、應用邏輯、UI都應該是非常類似,唯一不同的是調用不同的Factory 方法,由不同的產品類去處理與作業系統互動的資訊。
3、需要建立的對象是一系列相互關聯或相互依賴的產品族時,便可以使用抽象原廠模式。
三種原廠模式總結:
1.三種在形式和特點上極為相似,最終目的都是解耦。將對象的建立過程進行封裝,使用戶端可以直接得到對象,而不用去關心如何建立對象。
2.對比
Factory 方法模式:用於建立複雜物件。(單點食物)
抽象原廠模式:用於建立一組相關或相互依賴的複雜物件。(買套餐)
Factory 方法建立一般只有一個方法,建立一種產品。抽象工廠一般有多個方法,建立一系列產品。
我們不必去在意模式到底Factory 方法模式還是抽象原廠模式,因為他們之間的演變常常是令人琢磨不透的。明明使用的Factory 方法模式,當新需求來臨,稍加修改,加入了一個新方法後,由於類中的產品構成了不同等級結構中的產品族,它就變成抽象原廠模式了,而對於抽象原廠模式,當減少一個方法使的提供的產品不再構成產品族之後,它就演變成了Factory 方法模式。
PHP物件導向設計模式