将硬编码运费计算改为多态,核心是提取FreightCalculator接口,为express、standard、overseas等类型分别实现具体策略类,通过Map注册或Spring自动装配实现解耦、可扩展与易测试。

把硬编码逻辑改成多态,核心是识别“变化点”,抽出统一接口或抽象类,让不同行为由具体子类实现。不是为了多态而多态,而是为了解耦、可扩展、易测试。
识别可变逻辑,定义统一行为契约
先看硬编码里哪些分支在做“同一件事但方式不同”。比如一段 if-else 判断订单类型再计算运费:
if ("express".equals(orderType)) {
return weight * 12 + 5;
} else if ("standard".equals(orderType)) {
return weight * 8 + 2;
} else if ("overseas".equals(orderType)) {
return weight * 25 + 50;
}
这里的“计算运费”是统一动作,差异在于策略。应提取出 FreightCalculator 接口:
public interface FreightCalculator {
BigDecimal calculate(BigDecimal weight);
}
为每种逻辑创建独立实现类
每个 if 分支对应一个实现类,职责单一、无条件判断:
立即学习“Java免费学习笔记(深入)”;
- ExpressFreightCalculator:实现加急运费公式
- StandardFreightCalculator:实现标准运费公式
- OverseasFreightCalculator:实现海外运费公式
类名清晰表达意图,未来新增类型(如“carbonNeutral”)只需加新类,不改已有代码。
用工厂或策略容器解耦创建与使用
避免在业务逻辑中 new 具体实现类。推荐两种轻量方式:
- 简单工厂:传入 orderType 字符串,返回对应计算器(适合类型少、不常变)
-
Map 驱动策略注册:启动时将各实现类按 key 注册进
Map<String, FreightCalculator>,运行时查表获取(更灵活,支持热插拔)
调用方只依赖接口,完全不知道具体实现,也无需修改判断逻辑。
配合 Spring 可自动装配策略集合
如果项目用 Spring,可以利用 @Qualifier 或泛型工厂:
- 所有实现类加
@Component - 注入
Map<String, FreightCalculator>,key 默认为类名小写(如"expressfreightcalculator"),也可用@Value或自定义注解标注业务 key - 运行时根据 orderType 查 map,安全取值(建议 fallback 到默认实现或抛明确异常)
这样连工厂类都不用手写,框架帮你管理生命周期和查找。


















