Factory Method Pattern(工廠方法模式),與Abstract Factory Pattern抽象工廠,其實都是在做同一件事,

就是要把建構子(constructor )封裝起來,使人不能隨意的去使用、修改。   這個與Singleton其實都是在做相同的事情,

因此,這三個也很常被使用在一起。  或是任兩個合併使用。

 

最簡單的區分方法:我先列個簡單的小表 (但我其實覺得這個分法很不好…有興趣的人真的去抓一下兩邊的UML圖去看一下比較好

 

Factory Method  Abstract Factory
以class來達成loose coupling的目的 以object來達成loose coupling的目的
主要精神:inheritance(繼承) 主要精神:composition(合成)
當利用Factory Method來建立物件時,需要繼承一個
class,並且override掉原本的Factory Method 
利用Abstract Factory的時候:重點是需要先定義一個
concrete Factory(具象化的工廠) 
目的:只是讓使用者不再需要每次修改原始的class 可以將各種產品利用composition集合起來
  缺點:每一次要加入新產品:都必需要改變interface,甚至
需要將所有的工廠重新實作一次以適應新的interface 
建立一項商品: 建立一整個商品家族
在java中Factory會看到的字:abstract 在java中factory會看到的字:interface

我在想,大家之所以會常常把這兩個工廠搞混(書上說的,我以前也分不清楚),所以我就只寫在這裡…我想最主要的原因應該是:

工廠方法:裡面一定會看到abstract(抽象)這個字,而抽象工廠,卻是使用interface(介面) 這個key word,所以大家才容易搞混…

好吧…我必需要說…寫論文時也會發生類似的事…大家都喜歡一些特別的單字,使得那些單字都特別的搶手,先搶先贏,下好離手…自然就容易發生這種容易搞混的情形啦~

 


上面的是小抄:用來記錄兩種不同類型的factory所使用的最簡單的方法…

但如我所說:其實兩個pattern常常被合用,所以其實有時候很難去分辨究竟是哪個pattern

所以其實不是準備考試、或是教學一類,就不用分的太仔細了,重點是在於要理解他的精神以及目的。

 

重點都是在於要把constructor封裝起來,讓人不能隨意的去操作,

 

 

接下來我使用的是Head First Design Patterns 裡面的例子

Factory Method Pattern:

public abstract class PizzaStore{

   public Pizza orderPizza(String aType){

      Pizza pizza = createPizza(aType);

      pizza.prepare();

      pizza.bake();

      pizza.cut();

      pizza.box();

      return pizza;

   }

   public abstract Pizza createPizza();

}

這就是一個最簡單的Factory Method的例子:

重點在於createPizza這一個 method

此method必需要由subclass來定義,

接下來,看是什麼不同的pizza店,都可以靠createPizza來定義自己想要的pizza

比方說可以有:

public TaiwanPizzaStore extends PizzaStore{

  @override

  public Pizza createPizza(){

     //這邊可以加上各種台灣pizza的特殊作法

  }

}

這樣子一來,每當要新增不同的pizza製造方法時,只需要建立不同的PizzaStore工廠即可。

忽叫的方法都一樣…

 

比方說台灣的pizza工廠因為塑化劑而無法再食用,我們只需要換一個工廠

換成日本的pizza工廠,這樣子就不用擔心塑化劑了~~一樣可以製造~~(可是要怎麼送來台灣呢?這就是另外的故事了)

 

Abstract Factory則都是使用interface來使用:

 

public interface PizzaIngredientFactory{

    public Dough createDough();

    public Sauce createSauce();

    public Cheese createCheese();

    public Veggies[]  createVeggies();

...

}

 

接著就可以實作出不同的pizzaIngredientFactory了。

還是使用國家來分類的話~~不同國家的醬汁可以分

比方說四川的醬汁要辣一點,日本的醬汁要甜一點,美國的口味要比較重……

 

public class TWPizzaIngredientFacotry implements PizzaIngredientFactory

{

    public Dough createDough(){

       return new thickDough();  //為什麼台灣的pizza餅皮都要那麼厚呢?

    }

    public Sauce createSauce(){

         return new MarinaraSauce();//這邊就直接抄書上了

    }

    public Cheese createCheese(){  //台灣不產cheese,所以可以用各種cheese

        return new cheese();

    }

    .......

}

 

還可以靠定義不同的原料,來組合各種pizza(各種口味,各種國家)

 

 

Pizza的製作就很簡單了:

public class Pizza{

    PizzaIngredientFactory  mIngredientFactory;

   public Pizza(PizzaIngredientFactory  aIngredientFactory){

         mIngredientFactory  = aIngredientFactory;

   }

 

    ....

}

然後製作時就使用該factory得到物件…

 

 

-----

 

以上是簡單的例子,把大家容易搞混的地方舉出來

要真的搞懂這兩個在做什麼~請大家去翻書或是找線上教學~~這裡沒有

(除非讀者真的天才到我寫這樣子一小段你們就搞懂其工廠的精神了

 

 

----

其實最容易搞混的就這幾個吧~~Head First Design Patterns 我已經看完了,基本上沒有什麼會搞混了吧?

 

我會找時間再review一次,如果還有容易搞混的地方,我再來寫一篇3好了

arrow
arrow
    全站熱搜

    ccas 發表在 痞客邦 留言(2) 人氣()