《Head First設計模式》筆記整理...歡迎交流...編程
定義了一個建立對象的接口,但由子類決定要實例化的類是哪個。工廠方法讓類把實例化推遲到子類。
正如在正式定義中所說的,經常聽到其餘開發人員說,工廠方法讓子類決定要實例化的類是哪個。但願不要理解錯誤,所謂的「決定」,並非指模式容許子類自己在運行時作決定,而是指在編寫建立者類時,不須要知道實際建立的具體產品是哪個。選擇使用哪一個產品的子類,天然就決定看實際建立的產品是什麼。設計模式
要依賴抽象,不要依賴具體類。
這個原則聽起來很像「針對接口編程,不針對實現編程」。然而,這裏更強調「抽象」。這個原則說明了不能讓高層組件依賴低層組件,「二者」都應該依賴抽象。測試
幾個方法幫助你遵循此原則......this
若是覆蓋基類已經實現的方法,那麼你的基類不是一個真正適合被繼承的抽象。基類中已經實現的方法,應該由全部的子類共享。spa
須要注意的是,全部的原則都是爲了更好的設計,並非必須隨時都遵循的。設計
public abstract class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza; pizza = ceratePizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } public abstract Pizza createPizza(String type); //其它方法 } public class NYPizzaStore extends PizzaStore { Pizza createPizza(String item) { if(item.eauals(cheese)) { return new NYStyleCheesePizza(); } else if() { ... } } }
//工廠方法是抽象的,因此必須依賴子類來處理對象的建立 //工廠方法必須返回一個產品 //工廠方法將客戶,和實際建立具體產品的代碼分隔開來 //工廠方法可能須要傳遞參數(也可能不須要)來指定所須要的產品 abstract Product factoryMethod(String type)
public abstract class Pizza { String name; String dough; String sauce; ArrayList topppings = new ArrayList(); void prepare() { ... for(int i = 0; i < topppings.size(); i++) { System.out.printIn(" " + topppings.get(i)); //準備工做要以特定的順序進行,有一道連串的步驟 } }; void brake() { ... }; void cut() { ... }; void box() { ... }; Public String getName() { return name; }; } public NYStyleCheesePizza extends Pizza { public NYStyleCheesePizza() { name = "NY Style Suace and Cheese Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce"; topppings.add("Grated Reggiao Cheese"); } }
測試code
public class PizzaTestDrive { public static void main() { PizzaStore nyStore = NyPizzaStore(); Pizza pizza = nyStore.orderPizza("cheese"); System.out.printIn("Ethan ordered a " + pizza.getName() + "\n"); // Ethan ordered a NY Style Suace and Cheese Pizza } }
抽象工廠模式提供一個接口,用於建立相關或依賴對象的家族,而不準奧明確指定具體類。
抽象工廠容許客戶使用抽象的接口來建立一組相關的產品,而不須要知道(或關心)實際產出的產品是什麼。這樣依賴,客戶就從具體產品中被解耦。對象
再回到披薩店繼承
上面披薩店的設計已經很棒了,可是對不一樣地區的加盟店,,原料是不同的(如,紐約的紅醬料和芝加哥的醬料是不同的),可是流程是一致。如何解耦?建立一個原料工廠。接口
public class NYPizzaStore extends PizzaStore { protected Pizza createPizza(Stirng item) { Pizza pizza = null; PizzaIngredientFactory ingredientFactory = new PizzaIngredientFactory(); } if(item.equals("cheese")) { pizza = new cheesePizza(ingredientFactory); pizza.setName("new You Style Cheese Pizza"); } else if (...) { ... } return pizza; } public abstract class Pizza { String name; Dough dough; Sauce sauce; Veggies veggies(); chenegie veggues; Cheese cheeese; Perperroni pepperoni; clams clams; abstract void Prepare(); void bake() { ... } void cut() { ... } void box() { ... } void setName(String name) {} void setName() {} } public class CheesePizza extends Pizza { PizzaIngredientFactory ingredientFactory; public CheesePizza(PizzaIngredientFactory ingredientFactory) { this.ingredientFactory = ingredientFactory; } void prepare() { dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); } }