Abstract
template method pattern是我學到第二個pattern,算是一個很容易理解的pattern,但卻非常的實用。
Intent
對於operation,只先定義好演算法的輪廓,某些步驟則留給子類別去填補,以便在不改變演算法整體架構的情況下讓子類別去精鍊某些步驟。
其UML表示法
在實務上,我們可能本來有一個功能完整的class,但因為『需求改變』,新的class和原來的class幾乎60%相同, 只有40%不一樣,因此我們希望將60%相同部份的程式留下來,僅改寫40%不同的地方。
如本來某公司只生產『自動泡茶機』,後來為了增加產品線,想生產『自動泡咖啡機』,經過分析,兩台機器的架構相似,生產流程也相似。
自動泡茶機
step1 : 將開水煮開
step2 : 將<茶葉>放入開水
step3 : 將<茶>倒入杯子
step4 : 加上<檸檬>
自動泡咖啡機
step1 : 將開水煮開
step2 : 將<咖啡粉>放入開水
step3 : 將<咖啡>倒入杯子
step4 : 加上<糖>和<奶精>
很明顯的step1相同,但step2 ~ step4不相同,所以只需改寫step2 ~ step4,step1可以繼續使用。先設計一個DrinkMachine雛型,定義了生產過程和step1,因為step2 ~ step4各有差異,就留在繼承DrinkMachine的class去改寫,這就是template method pattern。
我們看看這個架構,日後若有新drink加入,DrinkMachine,TeaMachine,CoffeeMachine皆不用修改,符合OCP的closed for modification原則,若要加入新的class,只計程並改寫DrinkMachine即可,符合OCP的open for extension原則,所以是非常好維護的架構。
簡言之,template method pattern就是將不同的member function用class包起來,由derived class去改寫。
以下用C++實做template method pattern。
執行結果
感謝Quark提供template版本的template method寫法
2
3
4
5
6
Remark
strategy和template method目的相同,皆對『新需求』的不同演算法提供『擴充』的機制,但手法卻不同,strategy採用object的方式,利用delegation改變algorithm,而template method則採用class的繼承方式來改變algorithm,由於用到的是class的inheritance,所以在compile-time就已經決定要override的algorithm,run-time就無法再改了,但strategy用的是object手法,所以在run-time還可以透過換object改變algorithm。
GoF的原文如下
See Also
(原創) 我的Design Pattern之旅[1]:Strategy Pattern (初級) (Design Pattern) (C++) (OO C++) (Template C++)
Reference
GoF,Design Patterns,Addison Weseley Longman,1995
Scott Meyers,Effective C++ 3/e Item 35,Addison Wesley,2005