首页/开发/代码质量与评审速查/模板方法 Template Method(行为型)
设计原则与模式62 条

模板方法 Template Method(行为型)

在基类定义算法骨架,把可变步骤交给子类实现:复用流程、约束扩展点;注意钩子方法的默认行为要安全,别让子类必须实现过多步骤。

模板方法是什么

在基类里定义算法骨架,把可变步骤交给子类实现:流程顺序与固定步骤由基类掌控,子类只填差异部分。它用继承约束扩展点——子类能被改变的部分被限定在几个抽象方法或钩子里。现代语言里,回调与函数式参数是它更轻量的替代形态,不必为了一处差异引入继承层次。

基本信息

意图固定骨架 + 可变步骤
机制抽象步骤 + 钩子(hook,有默认实现)
约束骨架方法声明为 final,防止子类整体覆写
替代策略模式、回调函数、函数式参数

典型使用场景

  • 数据处理:打开、解析、分析、关闭的顺序固定,解析方式因格式而变
  • 框架回调:基类负责生命周期,子类实现钩子
  • 测试基类:统一的搭建与销毁流程,用例只写断言部分
  • 导出流程:查询、转换、写出三步固定,格式与模板可变
  • 算法族:同一流程的多种参数化实现,顺序不应由调用方控制

Java 示例

Java 示例
abstract class DataMiner {
    // 骨架:流程固定,子类不能整体覆写
    final void mine(String path) {
        byte[] raw = open(path);       // 固定步骤
        parse(raw);                    // 抽象步骤:子类必须实现
        analyze();                     // 钩子:有默认行为
        close();                       // 固定步骤
    }

    private byte[] open(String path) { /* 读写与资源管理留在基类 */ }
    protected abstract void parse(byte[] raw);
    protected void analyze() { }
    private void close() { }
}

扩展点类型

类型子类义务设计建议
抽象步骤必须实现数量越少越好,避免子类负担过重
钩子方法可选覆写,有默认行为默认实现要保守、不能有副作用
保护方法供子类复用的工具不要暴露内部可变状态
骨架方法不可覆写声明 final 并写清楚顺序含义
钩子方法的默认实现要安全:默认什么都不做,或给出最保守的行为。如果默认行为会写数据或发通知,子类作者不覆写它就会产生意外副作用。
只有一处差异时不必用继承:把可变部分作为策略对象或函数参数传入,能让流程与差异都保持可组合,也避免了「为一个变化点建一个类层次」的代价。

易错点

  • 骨架方法未声明 final:子类可整体覆写,流程约束失效
  • 钩子过多:子类被迫理解全流程细节,扩展点反成负担
  • 抽象步骤里做 I/O:测试必须带文件或网络环境,难以单测
  • 为了复用代码而用继承:子类与基类耦合在流程顺序上,改基类即影响所有子类

数据来源与参考

  • 《设计模式》(GoF)· Template Method
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌