策略模式用于解决业务逻辑分支爆炸问题,而非替代方法重载;当重载方法存在重复判断、共享核心逻辑或维护成本高时,应重构为策略模式+适配器,统一入参并解耦类型差异。

策略模式不是用来“替代”方法重载的,而是解决**业务逻辑分支爆炸**的问题;而方法重载是编译期多态,用于同一类中提供多种参数形式的调用入口。两者定位不同,但当重载方法内部出现大量重复判断或相似流程时,恰恰是策略模式可以介入的信号。
识别该重构的典型征兆
当你发现以下情况,就该考虑用策略模式代替“靠重载堆砌接口”:
- 多个重载方法最终都走向同一段核心逻辑(比如都调用 commonCalculation(...)),只是参数类型不同、需先做类型转换或字段提取
- 每个重载方法里都有相似的 if-else 或 switch 判断(如根据 type 或 source 决定走哪条路径)
- 新增一种参数类型,就得加一个重载 + 复制一遍校验和预处理逻辑,维护成本明显上升
- 单元测试要为每个重载单独覆盖,但实际差异只在输入适配,非算法本身
用策略模式+适配器解耦参数差异
核心思路:把“参数类型不同”这个变化点,封装成策略的输入适配过程,而不是靠重载暴露多个入口。
例如,原来有三个重载:
calculateAmount(QRequest q)<br>calculateAmount(CState c)<br>calculateAmount(RState r)
可重构为:
- 定义统一入参接口 AmountContext,含 getValue() 等共性方法
- 为每种原始类型写一个轻量适配器(QRequestAdapter、CStateAdapter),实现该接口
- 主方法只保留一个:calculateAmount(AmountContext context)
- 策略类(如 DefaultAmountStrategy)只关注 context.getValue() 的计算逻辑,不再感知原始类型
配合模板方法固化流程骨架
如果不同来源的数据还需差异化预处理(如 QRequest 需校验签名,CState 需查缓存),可在策略之上加一层模板方法:
- 抽象类 AmountCalculatorTemplate 定义标准流程:validate() → load() → compute() → format()
- 各子类(QRequestCalculator、CStateCalculator)只重写对应钩子方法
- 所有重载入口统一收口为 new XCalculator().execute(input)
这样既消除了重载泛滥,又把“何时校验”“何时加载”等流程控制权交还给架构,而非散落在各个重载方法里。
什么时候仍该保留重载
并非所有重载都要消灭。以下情况建议保留:
- 纯构造场景:如 new User(String name) 和 new User(String name, int age),语义清晰且无共享逻辑
- 基础工具方法:如 StringUtils.isEmpty(String) 和 isEmpty(CharSequence),只为提升调用便利性
- 参数差异带来显著性能差异(如 byte[] vs InputStream),且无法通过统一接口高效抽象
关键判断标准是:重载方法之间是否存在**可被提取的公共行为**。有,则策略+适配更稳;无,则重载本身已是最佳抽象。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











