工廠模式,故名思義,就是你要某種東西的工廠,它負責爲你生產產品,你只要拿來使用便可,無需關心如何生成。 編程
除了使用new操做符外,還有不少製造對象的方法。好比說工廠模式。在實際的應用中,咱們大量地初始化會形成「耦合」問題。那該怎麼辦? 設計模式
當遇到"new",就會想到"具體".什麼意思呢?當使用new對一個類進行實例化時,咱們使用的是實現,但不是接口。這樣一來,會致使代碼失去良好的彈性。由於彼此之間已經被你綁定到一塊兒了。例如: this
Person p = new Person();當有一羣相關的具體類時,就會看到這樣的代碼: spa
if(speaking){ 設計
Person p = new Person;} 對象
else if(singing) { Person p = new Person();} 接口
else if(dancing){ Person p = new Person(); } 內存
在上述代碼中,有一些要實例化的具體類,究竟要實例化哪一個,要在運行時由一些邏輯條件來決定。 ci
這樣的代碼,若需求再也不有新的變化還能夠,可是,若一旦有變化,就必須從新打開這段代碼進行檢查和修改。毫無疑問,這樣的代碼會形成部分系統更難維護和更新,並且也更容易犯錯。 產品
爲何?
僅從技術上來講,new沒錯,就是爲咱們在內存中申請一份空間,而後存儲臨時數據。若是在頭效率與可維護性性的角度上來講,就有些差強人意了。進而,便有大師們提出了 面向接口編程。一切都應當參照抽象,而不是具體實現。面向接口編程,能夠隔離掉之後系統可能發生的大量變化。由於,面向接口編程,經過多態能夠與任何新類實現該接口。接口,也相應地體現了OO原則:對擴展開放,對修改封閉。
下面內容引自 《HeadFirst 設計模式》:
識別變化的方面 假設你有一個比薩店,代碼實現以下:
Pizza orderPizza(){
Pizza pizza = new Pizza();
pizza.prepare(); // 作比薩前的準備
pizza.bake(); // 燒烤
pizza.cut(); // 切餅
pizza.box(); // 包裝
return pizza;
}
可是,當你須要更多比薩類型時,怎麼解決?因此,必須增長一些代碼,來"決定"適合的比薩類型,而後再"製造"這個比薩:
Pizza orderPizza(String type){ // type參數----比薩類型
Pizza pizza;
if(type.equals("cheese")){ pizza = new CheesePizza();}
else if(type.equals("greek")){ pizza = new GreekPizza();}
else if(type.equals("pepperoni")){ pizza = new PepperoniPizza();}
pizza.prepare(); // 作比薩前的準備
pizza.bake(); // 燒烤
pizza.cut(); // 切餅
pizza.box(); // 包裝
return pizza;
}
可是,若是要增長更多地比薩類型,咱們上面的這些代碼就又得從新寫過,並且有至關一部分是重複的。因此,此時應該考慮 封裝。
首先,把建立對象的代碼從orderPizza()方法中抽離出去,而後把這些代碼放在一個對象中,這個新對象只管如何建立比薩,若是任何對象想要建立比薩,直接找它就對了。
Pizza orderPizaa(String type){
pizza.prepare(); // 作比薩前的準備
pizza.bake(); // 燒烤
pizza.cut(); // 切餅
pizza.box(); // 包裝
}
這樣一來,就有了 工廠 SimplePizzaFactory; 當須要比薩時,就叫SimplePizzaFactory生產一個。如今,orderPizza()方法只關心從工廠獲得了一個比薩,而這個比薩實現了Pizza接口,因此能夠調用 prepare(),bake(),cut(),box()來分別進行準備、烘烤、切片、裝盒
public class SimplePizzaFactory{
public Pizza createPizza(String type){
Pizza pizza = null;
if(type.equals("cheese")){ pizza = new CheesePizza();}
else if(type.equals("greek")){ pizza = new GreekPizza();}
else if(type.equals("pepperoni")){ pizza = new PepperoniPizza();}
return pizza;
}
public class PizzaStore{
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory facatory){ this.factory = factory; }
public Pizza orderPizza(String type)
{ Pizza pizza ;
pizza = factory.createPizza(type); // 比薩工廠根據傳入的參數來生產相應的比薩
pizza.prepare();
pizza.bake();
pizza.cut(); pizza.box();
}
}
}
在上面的修改後,代碼之間已經不是很大程度地耦合了。並且,實現與擴展也較好地分離,從而提升了代碼的彈性。
待續...