模板方法模式的核心是定义算法骨架并延迟具体步骤实现:父类用final模板方法固化流程顺序,private/final方法封装不变逻辑,abstract方法强制子类实现可变步骤,hook方法支持可选定制,继承机制确保子类只负责“怎么做”而非“何时做”。

模板方法模式的核心,就是把业务流程中“不变的部分”抽出来统一管理,把“变的部分”留给子类灵活实现。它不靠接口或组合,而是用继承+抽象方法来固化骨架、开放细节。
明确哪些步骤是固定骨架,哪些要交给子类
先梳理业务流程的完整链条,区分出:
- 所有子类都必须执行、且逻辑完全一致的步骤:比如订单校验、日志记录、结果封装、异常兜底——这些直接在抽象父类里写成 private 或 final 的具体方法;
- 不同子类必须各自实现、不可跳过的步骤:比如“调用微信支付”和“调用支付宝支付”,这类用 protected abstract 声明,强制子类重写;
- 可选定制的辅助行为:比如是否发短信通知、是否刷新缓存、是否埋点统计——这类用 protected 钩子方法(带空实现),子类按需覆盖。
模板方法本身必须声明为 final
这是关键防线。模板方法(如 public final void processOrder())定义了整个流程的执行顺序,一旦被子类重写,骨架就塌了。它内部只调用父类自己的私有方法和子类必须/可选实现的 protected 方法,不暴露任何可被外部直接调用的业务步骤。
常见错误是把它写成 public 非 final 或 protected,导致子类意外覆盖流程,破坏设计意图。
子类只负责“怎么做”,不参与“什么时候做”
子类的任务非常清晰:只重写 abstract 方法和必要时覆盖钩子方法。它不能主动调用 super.processOrder(),也不该在自己方法里控制流程走向。流程调度权完全归属父类模板方法——子类是执行者,不是协调者。
客户端代码只需 new 一个具体子类(如 new WechatPaymentTemplate()),然后调用继承来的模板方法即可,无需关心内部怎么流转。
配合 Spring 等框架时注意解耦
不要在模板方法里 new 具体子类,也不要在父类里硬编码实现类。Spring 场景下,通常让子类标注 @Service 或 @Component,由容器管理,再通过策略选择器(比如根据 channelType 查找对应 Bean)注入并调用。这样既保持模板结构稳定,又支持运行时动态切换,也方便单元测试和 AOP 增强。


















