抽象类定义业务模板需锁死主干流程、精准留空核心逻辑、封装公共能力并预留钩子。用final execute()规定checkInventory→lockStock→createOrder→notifySupplier顺序,其中lockStock和createOrder为abstract;calculatePrice、getLockKey等关键决策点声明为protected abstract;提供generateIdempotentKey等protected final工具方法;onOrderCreated等protected空钩子供按需扩展。

用抽象类定义业务模板,关键在于把流程骨架收在父类、把核心变量逻辑“留空”交给子类填。不是写一堆空方法,而是精准识别哪些是必须统一的,哪些是必须定制的。
明确业务主干流程,用 final 模板方法锁死执行顺序
在抽象类中声明一个 public final void execute() 方法,里面按顺序调用准备、处理、收尾等步骤。这个方法不能被重写,确保所有子类都走同一路径。
- 比如订单履约流程:checkInventory() → lockStock() → createOrder() → notifySupplier()
- 其中 checkInventory() 和 notifySupplier() 可以有默认实现(如通用校验、基础通知)
- 但 lockStock() 和 createOrder() 是业务强相关,留作 abstract
把核心变量逻辑声明为 protected abstract 方法
所谓“核心变量逻辑”,是指影响结果的关键计算或决策点,比如定价策略、库存锁定规则、通知渠道选择。这些不能由父类硬编码,必须由子类根据业务场景决定。
- 例如:protected abstract BigDecimal calculatePrice(Order order);
- 又如:protected abstract String getLockKey(Order order);
- 访问修饰符用 protected 即可——仅限子类可见,不对外暴露,也避免了 public 带来的滥用风险
封装公共状态与工具能力,减少子类重复劳动
抽象类不是只留空,还要主动提供子类能直接复用的东西。比如统一的参数校验、日志上下文、重试机制封装、幂等 key 生成器。
- 定义 protected final String generateIdempotentKey(Order order) { ... }
- 定义 private void logStart(String step) { ... },在模板方法中直接调用
- 子类不用再自己写校验逻辑,只需关注“我怎么算价格”“我怎么锁库存”
预留钩子方法,应对少数子类的特殊干预需求
有些逻辑大多数子类不需要改,但个别场景要插一脚,比如风控增强、灰度开关、异步补偿。这时加一个空的 protected 方法即可。
- 例如:protected void onOrderCreated(Order order) { }
- A 子类重写它发审计日志,B 子类重写它触发延迟任务,C 子类完全不碰
- 模板方法里调用它,不影响主干,也不强制子类实现










