Head First 設計模式 —— 09. 模版方法 (Template Method) 模式

模板方法模式

在一個方法中定義一個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法中的某些步驟。 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