首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

深入淺出模板方法模式:JUnit 源碼實戰與擴展點控制藝術

     編輯:Java 程式設計入門

模式定義 (GoF)

定義一個操作中算法的骨架,將某些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。

結構角色

  • AbstractClass:定義抽象基本操作 (供子類實現) + 模板方法 (組裝算法骨架)
  • ConcreteClass:實現抽象基本操作,完成特定步驟

JUnit 經典案例:TestCase.runBare()


public abstract class TestCase {
    // 模板方法:定義測試算法骨架
    public void runBare() throws Throwable {
        setUp();                 // 1. 初始化
        try {
            runTest();           // 2. 執行測試 (抽象/鉤子)
        } finally {
            tearDown();          // 3. 清理 (保證執行)
        }
    }

    // 鉤子方法:預設空實現,子類可選覆寫
    protected void setUp() throws Exception {}
    protected void tearDown() throws Exception {}

    // 抽象方法:強制子類實現具體測試邏輯
    protected abstract void runTest();
}

關鍵設計決策:為什麼用「鉤子」而非「抽象」?

JUnit 選擇鉤子,因為測試未必需要初始化/清理資源。

適用場景檢核表

  1. 一次性實現算法不變部分,將可變行為委託子類
  2. 提取子類公共行為到父類,消除代碼重複 (良好編碼習慣)
  3. 控制子類擴展點:模板方法僅在特定點調用操作
    • 不想暴露模板方法 → private 或不在 API 中體現
    • 不想被覆寫 → final 修飾模板方法

模板方法 vs 策略模式

方案setUp/tearDown 為抽象setUp/tearDown 為鉤子 (空實現)
子類義務必須實現,哪怕不需要按需覆寫,無負擔
靈活性低高
適用場景步驟強制性強步驟可選、預設無操作

實戰避坑指南

  • 模板方法過長 → 拆分為多個受保護方法,每個單一職責
  • 鉤子方法過多 → 考慮策略模式或觀察者模式替代
  • 子類破壞骨架順序 → 模板方法 final、關鍵步驟 private 化
  • 濫用繼承 → 「組合優於繼承」,僅當「是一種」關係明確時用模板方法

模板方法模式是「好萊塢原則」的經典體現:「別調用我們,我們會調用你」。父類掌控流程,子類填充細節,實現復用與擴展的完美平衡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
維度模板方法策略模式
關係繼承 (靜態)組合 (動態)
算法骨架父類固定策略介面定義,可運行時切換
擴展方式新增子類新增策略實現類
適用性算法結構穩定、變化點固定算法整體可替換、需動態切換