工廠方法模式,定義為:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
UML
類別圖
PlantUML code
interface Creator { |
Before Using Pattern
原本有 Cat
類別和 Dog
類列是屬於動物類別,實作如下:
$cat = new Cat(); |
看程式碼可以思考出幾個問題:
- 如果類別行為修改的話,比方說多一個
setWalk()
方法,太棒了!程式所有new Cat()
new Dog()
的地方都必須修改。 - 兩種類別都是動物類別,行為會是相似的,今天如果加了一個新的類別叫
Rabbit
,太棒了!一樣的 code 全都要再 copy 一次。 - 承上,因為行為一樣,所以代表有一樣程式碼的地方可能都需要加個判斷,太棒了!要把所有
new Cat()
new Dog()
再找過一次再確認並修改。
這時就可以使用 Factory Method Pattern
解決上述問題
After Using Pattern
先寫一個產生動物的 method :
class Factory |
然後原本的程式碼(上層模組)改成這樣:
$cat = Factory::getAnimal('cat', 'Nyales'); |
從這兩段程式碼可以觀察出一些事:
- 會變動的因素轉變成 method 的引數,如:動物類型、動物名字等。
- 把物件固定行為包裝在 method 裡,如:動物叫聲、動物走路方法等。
- 回傳定義成 interface,這裡是定義回傳的物件是動物,所以未來有新的動物類別都可以在這裡加入。也可以從這個定義預期它取到的物件會有某種程度的共同性。
- 在 switch 的時候,通常習慣會寫一個會 throw exception 的 default,因為也許上層模組程式改好了,但底層忘了改,這時在 test 程式的時候馬上就會知道了。