接下來我們回過頭看第八章─樣板模式。
現在我們來看泡茶與泡咖啡的例子,它們有許多共通點:
例如這是泡咖啡的程式:
/*程式碼待補*/
而這是泡茶的程式:
/*程式碼待補*/
可以觀察到有些重複的程式碼,而這正是設計需要檢視的訊號─ 第一步我們可以將重複的部分抽象化,並放到基底類別中:
圖 1
但仔細觀察其中,還有一些可以再進一步整合的共通點:例如brewCoffeeGrinds()
與steepTeaBag()
其實都是"沖泡",而addSugarAndMilk()
與addLemon()
都是"加入調味料";因此可以更換成更通用的名字並讓它們也抽象化:
/*程式碼待補*/
類別圖變成這樣:
圖 2
而以上作的prepareRecipe()
,其實就已經是基本的樣板方法(template method) 模式了。它定義了演算法的步驟,讓子類別提供一個或多個步驟的實作。
樣板方法,顧名思義─prepareRecipe()
是個方法,而它也是演算法的"樣板" ,包裝了製作飲料的流程;在樣板中,這些演算法步驟都是用 "方法" 來表示,包含這個類別的方法(boilWater()
, pourIncup()
)與子類別各自實作的方法(brew()
、addCondiments()
)。
跟一開始咖啡跟茶各自實作比起來,使用樣板模式有哪些好處呢?可以整理如下:
我們其實已經掌握了樣板方法模式的運作方式,而它的具體定義如下:
樣板方法模式可在方法裡面定義演算法的骨架,並將一些步驟推遲至子類別處理;樣板方法可以讓子類別重新定義演算法的某些步驟,且不會改變演算法的結構。
它是一種幫演算法建立樣板─定義成一組步驟─的方法,讓整個結構維持不變但又能讓子類別提供實作。
它的類別圖如下
圖 3
接下來,我們來看看好久不見的新原則,還有它們之間的關係。