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好了
說的好,我欣賞。
回覆刪除很清楚的解說
回覆刪除令我知道2者的分別