點開這篇著你已經大致對Factory 方法有了一定的瞭解。但為什麼依然對這兩者的區別不是很明白,在搜尋了一天、看了許多文章後我有了一點想法,在這裡分享並記錄一下。
引用SO的一段文字:
One difference between the two is that with the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition whereas the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation.
這是說,Factory Method採用繼承的方式,將建立產品延遲到子類;而Factory Abstract採用組合的方式,將一系列相關的產品組合到一起。
其實抽象工廠中的每一個建立產品的介面都是一個Factory 方法,只不過Factory 方法建立一個產品,而抽象工廠建立一系列產品。
有個例子覺得非常簡單又能說明問題:Shape。
假設現在有Circle和Rectangle兩種Shape,而Client代碼需要根據情況建立一個具體的Shape。
Factory Method:
Factory 方法由介面IShapeFactory中的CreateShape提供,方法建立一個Shape,但至於具體返回怎樣的Shape,是由子類來完成的。對於CircleFactory,它實現Factory 方法並返回一個Circle對象,RectangleFactory工廠則返回一個Rectangle對象。
好了,現在Client代碼想要一個Circle對象,則它不用自己出馬,請具體的工廠來代工。
IShapeFactory shapeFactory = new CircleFactory()//建立一個可以生產Circle的工廠Shape shape = shapeFactory.CreateShape();//Circle工廠負責建立一個Circle產品//Now, client could use this 'Circle' shape happily...
現在,你希望建立一個帶有顏色的Shape,比如RedCircle、GreenRectangle等等組合。在你手上有許多Shape,也買好了許多顏料,你希望工廠能夠為你生產五顏六色的產品。依靠原廠模式的思想,將具體類的執行個體化與客戶代碼分離,由工廠負責生產具體的產品。
RedCircle產品 = Circle產品 + Red產品
每個工廠實際上要將有關係的產品組合在一起,為你建立出一個完整的產品。我想這就是為什麼SO那段引用裡說“抽象原廠模式利用組合”的原因吧。
Abstract Factory:
這張圖看起來複雜,其實很簡單不要慌張。
與Factory Method不同的是,Abstract Factory只是能夠生產一系列產品而已。它的做法無非是將相關的產品放在一起,由工廠一個個地來生產它們。你很聰明,其實抽象工廠裡隱含著Factory 方法的影子。一個個地CreateXXX其實就是Factory 方法嘛。
你想要一個綠色的矩形:
IColorfulShapeFactory greenRectangleFactory = new GreenRectangleFactory();//請綠色矩形工廠來生產ColorfulShape colorfulShape = new ColorfulShape(greenRectangleFactory);//使用綠色矩形工廠生產的產品來執行個體化一個具體的GreenRectangle//Now, 你可以為所欲為了...
與Factory Method略有不同的是,由於Abstract Factory生產一組產品,而你要的是一個完整的產品(它由這一組子產品構成),因此在ColorfulShape中,我們把工廠生產的產品用來初始化,這樣就構成了一個完整的產品。
Conclusion:
1. Factory Method 生產一個產品;Abstract Factory 生產一組產品;
2. 在 Factory Method 中,每一個CreateXXX方法實際上都是一個Factory Method ;
3. 當需要擴充一個產品時,對於Factory 方法來說只需要再實現一個生產這個產品的工廠就可以了,而對於抽象工廠來講,因為最終的產品是由許多子產品組合而成的,因此就顯得麻煩了多:
還是以ColorfulShape產品為例。
a. 改動發生在原子產品上,如增加一個藍色,那隻需要實現幾個能夠生產BlueShape的工廠;
b. 改動發生在新子產品上,如你又想為ColorfulShape增加一個特性-----夾心材料(假設你在生產一款五顏六色、形狀各異的夾心糖果,p.s.我實在想不來加什麼屬性好了。。),那就需要更改抽象工廠的介面,並牽連至所有實現了該介面的具體工廠。
可以看到,不論如何改動都比Factory Method來的大。
=====
以上是個人的一些理解,希望在沒有誤導你的前提下,對你能夠有些協助。不妥之處還懇請指出。