本章主軸#
樣板方法模式(Template Method)解決另一種變動:步驟一致、實作不同。它在抽象類別中固定流程骨架,把可變的步驟下放給子類實作。也常被用來消除「複製貼上 + 微改」造成的重複。
案例:支援多種 SQL 資料庫#
要同時支援 Oracle 與 SQL Server。雖然兩者皆遵循 SQL 標準,但細節不同。執行查詢的高層步驟卻是一樣的:
- 格式化 CONNECT 指令
- 送出 CONNECT
- 格式化 SELECT 指令
- 送出 SELECT
- 回傳結果集
差別只在某些步驟的「格式化」實作。
GoF 對 Template Method 的意圖描述#
在一個操作中定義演算法的骨架,把某些步驟延遲到子類別。讓子類重新定義這些步驟,但不改演算法的結構。
套到案例上#
- 抽象類別
QueryTemplate內有doQuery()方法,照五個步驟跑流程 - 抽象方法
formatConnect()、formatSelect()留給子類實作 OracleQT、SQLSvrQT各自提供具體實作

Figure 19-1: 用 Template Method 執行查詢——doQuery 框架共用,formatConnect/formatSelect 由子類提供
多型在這裡的關鍵:透過
QueryTemplate參考呼叫doQuery(),但因為實際物件是OracleQT,所以formatConnect會解析到 Oracle 的版本。
新支援哪種資料庫?只需新增一個衍生類別,照「樣板」填空。
用 Template Method 消除重複#
作者另一段經驗:團隊面對許多相似但細節不同的合作夥伴系統,採用 if-then-else 與複製貼上交替——程式碼愈來愈難維護。
複製貼上後的兩種重複#
- 明顯的重複:完全沒改的那幾行
- 流程重複:步驟順序相同,只有實作不同
重構流程#
- 用「Extract Method」把會變的部分抽成獨立方法(即使尚未要泛化)
- 建立基底類別承載不變的
someMethod - 寫第二個衍生類別實作其變化部分
「先用 Extract 把變動的部分抽出,再建立基底承接」其實就是 GoF「找出變動並封裝」的具體流程。
若一開始就 program by intention,這一步會自然發生。
重構與 OCP 的兩段式手法#
| 步驟 | 內容 |
|---|---|
| 1. 重構但不加新功能 | 讓即將加入的功能可以「插」進來而不必改既有程式 |
| 2. 加入新功能 | 只動新類別與工廠 |
知道模式,能讓你在 XP 風格的開發中也用得上「先重構、再擴充」的雙步驟。
一個沒接觸過模式的設計者,常根本沒察覺自己在重複——而模式提供了思考的工具。
Template Method 的關鍵特性#
| 欄位 | 內容 |
|---|---|
| Intent | 在操作中定義演算法骨架,把某些步驟下放到子類 |
| Problem | 高層流程一致,低層實作有變化 |
| Solution | 抽象方法定義可變步驟,呼叫關係寫死在基底 |
| Consequences | 適合代碼重用;若步驟需獨立變動,應改用 Strategy |
| Implementation | 抽象方法在基底類別、衍生類別補上具體實作 |

Figure 19-7: Template Method 模式的通用結構——AbstractClass 定義骨架,ConcreteClass 提供原始操作
實務筆記#
Template Method ≠ 一組捆在一起的 Strategy#
兩者結構乍看相像,但 Template Method 的可變步驟緊密耦合——它們是同一個流程的環節,會「一起」變。Strategy 則代表互相獨立的可換演算法。
若把 Template Method 想成「幾個 Strategy 的集合」,可能會被誤導去做不必要的解耦,反而失去靈活度。
本章重點#
- Template Method 用來把「流程一致、步驟實作不同」的情境抽象化
- 抽象類別保留骨架,子類提供步驟實作
- 是消除「複製貼上 + 微改」型重複的標準手法
- 它強調步驟之間的捆綁——若步驟間是獨立的,請改用 Strategy