2012年10月22日 星期一

Factory Method

目的
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
(定義可資生成物件的介面,但讓子類別去決定該具現出哪一種類別的物件。此模式讓類別將具現化程序交付給子類別去處置。 [1])



Factory Method 從字面上看來,這 Pattern 是一個 method,主要功能就跟 factory 一樣負責製造產品
沒錯,正是如此,但這聽起來挺抽象的,到底是什麼意思呢,舉個例子:
往往在開發過程中會遇到一種狀況就是
不知道會需要哪些確切物件,因此沒辦法生成這些物件
但知道這些物件會有一些共同的操作或屬性
這時候就可以使用 Factory Method
把生成物件的過程延到之後處理,先定義生產的介面溝通
另外把物件的共同操作或屬性也定義出共同的介面
因此透過這 Pattern,即使工廠內部做任何改變,外部的使用者操作行為皆能一致,不需做任何改變

Factory Method 的 UML Class Diagram:

AbstractCreator 和 AbstractProduct 這兩個 Class 皆是 interfaces
而 AbstractCreator 會有一個 factoryMethod()
在 C++ 中,factoryMethod() 會是 (pure) virtual function
子類別來決定要怎麼製造產品
Client 不需要煩惱怎麼製造出產品,並且也可以和未知的 ConcreteProduct 合作

範例程式(製紅茶工廠):

範例程式與 Class Diagram 的對應關係:

  • Client <==> main
  • AbstractCreator <==> TeaAbstractCreator
  • ConcreteCreator <==> BlackTeaCreator
  • AbstractProduct <==> Tea
  • Product <==> BlackTea


基本上一個 ConcreteCreator 就會對應到一個 ConcreteProduct
透過這樣的方法,可以把 Simple Factory 的 branching statement拿掉
如此當加入新的產品時,便可以原封不動原本寫好的程式
只需要在額外增加新產品的 Class 與對應的 Creator 即可
此外,可以把 Simple Factory 加入到 Factory Method 中
如此就變成參數化的 Factory Method
各位有空可以自己試試看 :)

理解 Factory Method 的概念後,不妨回到最前面看看那原本難懂的目的
也許可以更能了解 Factory Method 魅力所在

註:在範例程式中 buyTea() 運用到另一個 Design Pattern: Template Method
之後會有更進一步的說明

[1] "物件導向設計模式", Gamma, Johnson, Helm, Vlissides 著, 葉秉哲譯