模板方法模式的核心是定义固定算法骨架并延迟具体步骤至子类实现:抽象类中用final模板方法锁定流程顺序,通过abstract方法强制子类实现关键步骤,钩子方法提供可选扩展,所有步骤以this.xxx()调用确保多态生效。

抽象类中的模板方法模式,核心是“定义算法骨架,把具体步骤延迟到子类实现”。它不靠强制约束,而是靠设计——把不变的部分写死在抽象类里,可变的部分用抽象方法或钩子方法留空,让子类去填。
骨架固定:在抽象类中写死流程顺序
模板方法本身必须是 final 的(防止子类重写流程),内部按逻辑顺序调用一系列方法。这些方法有些是已实现的具体步骤,有些是 abstract 或默认空实现的钩子。
- 把算法中每一步的执行顺序明确写在模板方法里,比如
prepare() → cook() → serve() - 所有步骤调用都用 this.xxx(),确保运行时多态生效(子类重写的 cook() 才会被调)
- 不要在模板方法里写 if/else 分支来切换逻辑——那是破坏骨架;该分支的判断应放在钩子方法里
延迟实现:用 abstract 方法 + 钩子方法配合
不是所有留空都得用 abstract。区分两类延迟点:
-
abstract 方法:子类必须实现,否则编译不通过(如
cook()) -
钩子方法(hook):有默认空实现(
void onReady() {}),子类可选重写(如定制日志、预处理)
例如:public abstract class CoffeeTemplate { public final void make() { boilWater(); brew(); pourInCup(); onAddCondiments(); } protected abstract void brew(); protected void onAddCondiments() {} }
立即学习“Java免费学习笔记(深入)”;
关键细节:访问权限与调用时机要合理
模板方法里的步骤方法通常设为 protected,既不让外部直接调用,又允许子类覆盖。避免用 private(子类无法重写),也别用 public(破坏封装,用户可能误调某一步)。
- 初始化类成员、校验参数等前置工作,放在模板方法开头做(由父类控制)
- 资源清理、收尾通知等后置动作,放在模板方法末尾,并考虑用 hook(如
onComplete()) - 若某步可能失败,应在模板方法中统一 try-catch,而不是让每个子类自己处理异常逻辑
避免常见陷阱
模板方法容易被误用成“过度设计”,注意这几点:
- 别把所有方法都 abstract——只抽象真正会变的部分;稳定逻辑就实现在父类
- 子类不应重写模板方法本身(所以加 final),也不应绕过它直接调用中间步骤(破坏流程一致性)
- 如果子类需要跳过某步,用钩子返回布尔值控制(如
shouldBrew()),而不是删掉调用


















