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

Java 設計模式精講:模板方法模式——定義算法骨架,延遲子類實現

     編輯:Java 綜合教學

Java 設計模式精講:模板方法模式——定義算法骨架,延遲子類實現

模板方法模式是**基於繼承的代碼復用核心技術**,屬於類行為型模式。它將算法的**不變部分**封裝在父類模板方法中,**可變部分**抽象為基本方法由子類實現,實現「好萊塢原則」:Don't call us, we'll call you。

一、核心角色與職責

角色職責關鍵點
抽象模板1. 定義抽象基本方法 (強制子類實現)
2. 實現模板方法 (最終 final,調用基本方法組裝算法骨架)
3. 可提供鉤子方法 (空實現,子類可選覆寫)
算法骨架守護者,控制流程順序
具體模板實現父類抽象基本方法,提供差異化邏輯每個具體類對應一種算法變體

二、經典案例:動物展示

抽象模板

public abstract class Animal {
    // 基本方法:抽象,強制子類實現
    public abstract String info();

    // 模板方法:final 禁止覆寫,鎖定算法骨架
    public final void show() {
        System.out.println(info() + "我是最聰明的動物");
    }
}

具體模板

public class Cat extends Animal {
    @Override public String info() { return "我是一只貓"; }
}
public class Dog extends Animal {
    @Override public String info() { return "我是一條狗"; }
}

客戶端

public class Test {
    public static void main(String[] args) {
        Animal a1 = new Dog(); a1.show(); // 我是一條狗我是最聰明的動物
        Animal a2 = new Cat(); a2.show(); // 我是一只貓我是最聰明的動物
    }
}

三、模板方法中的三種基本方法

類型關鍵字實現者子類可否覆寫用途
抽象方法abstract子類**必須**實現是 (強制)算法核心差異步驟
具體方法無/ final父類實現否 (建議 final)算法通用固定步驟
鉤子方法無/ protected父類提供空/默認實現是 (可選)算法可選擴展點、條件判斷

鉤子方法實例

public abstract class ReportGenerator {
    // 模板方法
    public final void generate() {
        collectData();
        if (needChart()) {       // 鉤子方法控制流程
            buildChart();
        }
        renderReport();
    }

    protected abstract void collectData();   // 抽象方法
    protected abstract void renderReport();  // 抽象方法

    protected void buildChart() {            // 具體方法
        System.out.println("構建通用圖表...");
    }

    protected boolean needChart() {          // 鉤子方法:默認 true
        return true;
    }
}

public class SimpleReport extends ReportGenerator {
    @Override protected void collectData() { System.out.println("收集簡易數據"); }
    @Override protected void renderReport() { System.out.println("渲染簡易報表"); }
    @Override protected boolean needChart() { return false; } // 覆寫鉤子:不需要圖表
}

四、模板方法 vs 策略模式:繼承 vs 組合

維度模板方法策略模式
核心機制繼承 (is-a)組合/委派 (has-a)
算法骨架位置父類 (固定)上下文類 (可運行時切換)
可變部分子類重寫方法策略接口實現類
擴展方式新增子類新增策略類 + 注入
耦合度較高 (繼承耦合)較低 (接口耦合)
適用場景算法骨架穩定、變體較少、編譯時確定算法族並存、需運行時動態切換

五、JDK / 框架源碼中的模板方法

  • HttpServlet:service() 模板方法 → 分發 doGet()/doPost() (基本方法)
  • AbstractList:addAll() 模板 → 循環調用 add() (基本方法)
  • JdbcTemplate:execute() 模板 → 回調 PreparedStatementCallback (鉤子/回調)
  • HibernateTemplate、RedisTemplate 等 Spring 模板類
  • InputStream.read():模板方法調用抽象 read(byte[])

六、設計原則體現

  1. 開閉原則:擴展新變體只需新增子類,不修改父類骨架
  2. 單一職責:父類負責流程控制,子類負責具體實現
  3. 里氏替換:子類實現基本方法不改變父類協議
  4. 好萊塢原則:父類調用子類方法,反轉控制流

七、避坑指南

  • 模板方法**必須加 final**,防止子類破壞算法骨架
  • 基本方法**盡量 protected**,封裝內部細節
  • 抽象方法數量**不宜過多** (超過 3-4 個考慮策略模式),否則子類實現負擔重、碎片化
  • 鉤子方法命名建議 needXxx()、beforeXxx()、afterXxx(),語義清晰
  • 避免在基本方法中調用模板方法,防死循環

八、總結

模板方法模式以**「父類定骨架、子類填肉」**的極簡哲學,解決了算法家族中**結構固定、細節多變**的經典問題。它是框架設計的基石(JDK、Spring 大量應用),也是理解「控制反轉」最直觀的入門模式。掌握其**三種基本方法分類、final 鎖定骨架、鉤子方法靈活控制流**,即可在框架擴展、業務流程標準化、代碼去重場景中遊刃有餘。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved