Simple Factory Pattern

工廠模式,故名思義,就是你要某種東西的工廠,它負責爲你生產產品,你只要拿來使用便可,無需關心如何生成。 編程

除了使用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();

}

}

}

在上面的修改後,代碼之間已經不是很大程度地耦合了。並且,實現與擴展也較好地分離,從而提升了代碼的彈性。

待續...

相關文章
相關標籤/搜索