模板方法模式
在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。 P289
特點
- 主導演算法框架,並且保護這個演算法
P288
- 最大化複用程式碼
P288
- 演算法只存在於一個地方,容易修改
P288
- 專注演算法本身,由子類提供完整的實現
P288
- 模板方法本身和內部具體操作解耦
P289
設計原則
好萊塢原則:低層元件別呼叫高層元件,讓高層元件呼叫低層元件。 P296
優點
- 防止依賴腐敗(依賴腐敗會使使用者難以弄懂系統的設計)
P296
思考題
還有哪些模式採用了好萊塢原則? P297
- 工廠方法、觀察者
- 抽象工廠、外觀、命令
思考題
我們知道應該多用組合,少用繼承。 sort()
模板方法的實現決定不使用繼承, sort
方法被實現成一個靜態的方法,在執行時和 Comparable
組合。這樣的做法有何優缺點?你如何處置這個難題?難道 Java 陣列讓這一切變得特別麻煩嗎? P305
優點
- 解耦了陣列和物件,避免讓物件陣列繼承陣列
缺點
- 可排序陣列的物件必須是
Comparable
的子類,比較邏輯沒法動態改變- 可以採用
Comparator
介面,該介面接受兩個待比較的物件,返回比較結果;並在sort
方法加上一個Comparator
引數
- 可以採用
難道 Java 陣列讓這一切變得特別麻煩嗎?
- Java 陣列不是將這一切變得麻煩的主要原因,而是 Java 陣列和物件陣列的沒有太多的聯絡,不能有太多耦合,所以不應該使用繼承。(如果物件陣列繼承 Java 陣列,則要求物件本身是
Comparable
的子類,極大地限制了陣列的使用場景和範圍)
思考題
想一想另一個模式,它是模板方法的一種特殊情況,原語操作用來建立並返回物件。這是什麼模式?
- 工廠方法模式、抽象工廠模式
所思所想
- 感覺模板方法就是在內部委託了多個策略,交給子類實現具體策略。其實平常寫程式碼中,經常無意中會用到這種思想。比如在處理 excel 檔案匯入時,步驟相對固定,先進行各種校驗,然後處理 excel 檔案(根據請求的不同解析成不同的物件入庫),最後返回匯入結果。當時我就把處理 excel 檔案這步抽出來,順便使用了一下函式式介面。
public Result handleExcel(File excelFile, ExcelConsumer consumer) {
// 各種校驗
boolean success = consumer.consume(excelFile);
// 構建結果封裝物件,並返回
}
本文首發於公眾號:滿賦諸機(點選檢視原文) 開源在 GitHub :reading-notes/head-first-design-patterns