設計模式 一 工廠方法Factory Method(工廠模式)
阿新 • • 發佈:2019-01-10
<?php /** * 工廠方法模式演變 * * 比薩加盟店 * 背景:隨著比薩店的發展,有更多人想成為比薩加盟店。 */ /** * 每家加盟店都可能想要提供不同風味的比薩(比方說紐約、芝加哥、加州),這受到了開店地點影響。 */ /** * 我們已經有一個做法。。。 * 如果利用SimpleFactory,寫出三種不同的工廠,分別為NYPizzaFactory、ChicagoPizzaFactory、CaliforniaPizzaFactory,那麼各地加盟店都有適合的工廠可以使用,這是一種做法。 */ $NYPizzaFactory = new NYPizzaFactory(); $nyStore = new PizzaStore($NYPizzaFactory); $nyStore->orderPizza("veggie"); $ChicagoPizzaFactory = new NYPizzaFactory(); $chicagoStore = new PizzaStore($ChicagoPizzaFactory); $chicagoStore->orderPizza("veggie"); /** * 但是你想要多一些質量控制。。。。 * 在推廣SimpleFactory時,你發現加盟店的確是採用你的工廠建立比薩,但其他部分,卻開始採用他們自創的流程。 * 烘烤的做法有些差異、不要切片、使用其他廠商的盒子。 */ /** * 讓子類決定,給比薩店使用框架。 * 有個做法可以讓比薩製作活動侷限於pizzaStore類,而同時又能讓這些加盟店依然可以自由製作該區域的風味。 * 所有做的事情,就是把 createPizza() 設定為“抽象方法”,然後為每個區域風味建立一個PizzaStore 的子類。 * 抽象、介面實現多型。 */ abstract class PizzaStore { //public $factory; //public function __construct(SimpleFactory $simpleFactory ) { // $this->factory = $simpleFactory; //} public function orderPizza($type) { //為了讓系統有彈性,我們很希望這是一個抽象類或介面。 //$pizza = $this->factory->createPizza($type); //變化部分 $pizza = $this->createPizza($type); $pizza->prepare(); //準備 $pizza->bake(); //烘烤 $pizza->cut(); //切片 $pizza->box(); //包裝 return $pizza; } abstract public function createPizza($type); } /** * 現在已經有了PizzaStore 超類,讓 NYPizzaStore,ChicagoPizzaStore等 都繼承這個PizzaStore,由子類決定如何製作比薩。 * */ /** * 子類如何做決定 * 關於這個方面,需要從PizzaStore的orderPizza()方法觀點來看,更進一步地,orderPizza()方法對pizza做了許多事情(準備、烘烤、切片、包裝) * 但由於Pizza物件是抽象的,orderPizza()並不知道哪些實際的具體類參與了進來,這不是orderPizza()方法決定的,換句話,這就是解耦。 * 那麼,子類是實時作出這樣的決定嗎?不是,但從orderPizza()的角度來看,如果選擇在NYStylePizzaStore訂購比薩,就是由這個子類(NYStylePizzaStore)決定。 * 嚴格來說,並非由這個子類實際做“決定”,而是由“顧客”決定到哪一家風味比薩店才決定了比薩風味。 */ class NYPizzaStore extends PizzaStore { public function createPizza($type) { if ("cheese" == $type) {//乳酪比薩 $pizza = new NYStyleCheesePizza(); } elseif ("greek" == $type) {//希臘比薩 $pizza = new NYStyleGreekPizza(); } elseif ("pepperoni" == $type) {//香腸比薩 $pizza = new NYStylePepperoniPizza(); } else { return null; } return $pizza; } } $NYPizzaStore = new NYPizzaStore(); $pizza = $NYPizzaStore->orderPizza('cheese'); /** * 注意 orderPizza 已經實現了createPizza */ /** * 總結 * 工廠方法模式 定義了一個建立物件的介面,但由子類決定要例項化的類時哪一個。工廠方法讓類把例項化推遲到子類。 * 問:簡單工廠與工廠方法的差異 * 答:工廠方法是用繼承擴充套件了一個類,而簡單工廠,工廠是另一個pizzastore使用物件。 * 子類的確看起來像簡單工廠。簡單工廠把全部的事情,在一個地方處理完了。然而工廠方法卻是建立一個框架,讓子類決定要如何實現。 * 比方說,在工廠方法中,orderPizza()方法提供了一般框架,以便建立比薩。orderPizza()依賴工廠方法建立具體類,並製造出實際的比薩。 */
參考資料 :Head First 設計模式