最高效重构继承的方式是优先识别并替换滥用的继承结构:深度继承链、多继承混用、子类只重写不复用父类逻辑;改用组合替代继承,将能力抽象为接口,按需注入策略组件,仅保留继承表达真正共享的骨架流程。
直接用“最常用继承写法”重构复杂业务逻辑,往往适得其反。真正高效的做法是:**优先识别并替换掉那些看似“常用”、实则滥用的继承结构**——比如深度继承链、多继承混用、子类只重写不复用父类逻辑等。这些写法在遗留系统中高频出现,但恰恰是耦合高、难测试、易出错的根源。
先揪出三类典型“伪常用”继承问题
别急着改代码,先看继承是否真在表达“是一个”关系:
- 子类大量重写父类方法,却只调用 super 的一小部分:比如 OrderService 父类有 10 个方法,VIPOrder 只用其中 2 个,其余全重写为空或 throw;这说明不是“继承”,而是“强行挂靠”
- 子类对父类某功能完全无感,但删不掉:例如 ExportService 继承了 EmailNotifier,可导出报表根本不需要发邮件;这种“搭便车式继承”暴露职责混乱
- 新增变体就加一层继承,但新旧类没语义关联:比如加了个 FlashSaleOrder 继承自 NormalOrder,只为了改库存检查逻辑——这不是“订单的一种”,而是“用了不同库存策略的订单”
用组合替代继承:不是换写法,是换建模思路
把“我是什么”转为“我需要什么能力”:
- 把价格计算、库存校验、通知发送等能力,分别定义为接口(PriceCalculator、InventoryChecker、Notifier)
- 每个具体场景选配实现:VIP 订单注入 VIPPriceCalculator,秒杀订单注入 RedisInventoryChecker
- Spring Boot 中直接 @Autowired 注入,无需 new,也无需修改类结构
保留继承仅用于真正共享的骨架流程
不是禁用继承,而是收窄它的职责范围:
- 只让抽象基类承载不可变模板:比如统一事务边界、日志埋点入口、异常标准化包装
- 所有业务判断(如“是否走优惠券”“是否要扣减赠品库存”)全部下沉到组合进来的策略组件里
- 这样父类稳定不变,子类灵活可插拔,升级时只需换组件,不动继承树
配合视图与适配器,平滑过渡老数据和老调用
重构业务逻辑时,数据库和外部依赖也要同步解耦:
- 用 SQL 视图隔离物理表变更:先 RENAME users → users_legacy,再建 VIEW users 暴露兼容字段,避免下游 SQL 报错
- 对无法立刻重写的第三方调用,封装成适配器:比如 LegacyPaymentApiAdapter 实现统一的 PaymentService 接口,内部转发旧 SDK
- 权限和外键需手动补全:视图默认不继承原表权限,记得 GRANT SELECT ON users TO app_user

















