3.11 模板方法模式
模板方法模式(Template Method)在父类里定义一个算法的骨架,把其中某些步骤延迟到子类实现。算法的整体结构固定不变,只有可变的步骤交给子类填充——“好莱坞原则”由此而来:别打电话给我,我会打给你(父类调用子类,而不是反过来)。
冲泡茶和咖啡几乎是同一套流程:烧水 → 冲泡 → 倒杯 → 加调料。只有“冲泡”和“加调料”不同。下面的实验让你切换茶/咖啡,看哪些步骤共享骨架、哪些被子类重写。
正在加载交互实验...
固定骨架,开放步骤
java
abstract class Beverage {
// 模板方法:用 final 锁住步骤顺序
public final void prepare() {
boilWater();
brew(); // 抽象步骤
pourInCup();
addCondiments(); // 抽象步骤
}
private void boilWater() { /* 共享 */ }
private void pourInCup() { /* 共享 */ }
protected abstract void brew();
protected abstract void addCondiments();
}prepare() 被声明为 final,子类不能改步骤顺序,只能填充被声明为抽象的那几步。这保证了算法骨架的稳定。
钩子方法:可选的介入点
除了抽象步骤,模板方法还能提供钩子(hook)——父类给一个默认(通常为空)实现,子类可选重写:
java
protected boolean customerWantsCondiments() { return true; } // 钩子下面的数据管道实验让你开关“校验”和“格式化”两个钩子,观察固定步骤始终执行、可选钩子按需启用,而顺序永远不变。
正在加载交互实验...
正在加载概念检查...
正在加载概念检查...
取舍
- 好处:消除重复的算法骨架,把公共流程提到父类,差异留给子类。
- 代价:依赖继承,灵活性不如策略模式(编译期绑定、单继承限制)。当你需要运行时切换整套算法时,策略更合适;当多个变体共享大量骨架、只在少数步骤不同时,模板方法更自然。
许多框架的“生命周期回调”(如 onCreate、render、测试的 setUp/tearDown)本质都是模板方法。
正在加载本节练习...