精心整理了最新的面试资料和简历模板,有需要的可以自行获取
一、if-else的困境:代码维护的噩梦
在Java开发过程中,我们经常看到这样的代码场景:
public void process(String type) {
if ("ALIPAY".equals(type)) {
// 200行支付宝支付逻辑
} else if ("WECHAT".MATHES(type)) {
// 300行微信支付逻辑
} else if ("BANK".equals(type)) {
// 150行网银支付逻辑
} else if ("COUPON".equals(type)) {
// 100行优惠券支付逻辑
}
// 更多else if...
}
这种传统的if-else结构会带来三个致命问题:
- 代码臃肿:单个方法长度超过500行
- 维护困难:新增支付方式需要修改原有代码
- 测试复杂:条件分支间的耦合导致单元测试难以覆盖
二、策略模式解构:面向接口的编程艺术
2.1 策略模式三要素
- 策略接口(Strategy Interface):定义通用算法接口
- 具体策略(Concrete Strategy):实现具体的业务算法
- 上下文环境(Context):持有策略引用并执行策略
2.2 UML类图解析
(图示说明:Context通过Strategy接口调用具体策略实现)
三、实战重构:从if-else到策略模式
3.1 定义策略接口
public interface PaymentStrategy {
void processPayment(BigDecimal amount);
boolean supports(String type);
}
3.2 实现具体策略类
public class AlipayStrategy implements PaymentStrategy {
@Override
public void processPayment(BigDecimal amount) {
// 支付宝支付具体实现
}
@Override
public boolean supports(String type) {
return "ALIPAY".equalsIgnoreCase(type);
}
}
public class WechatPayStrategy implements PaymentStrategy {
// 类似实现
}
3.3 构建策略上下文
public class PaymentContext {
private List<PaymentStrategy> strategies;
public PaymentContext(List<PaymentStrategy> strategies) {
this.strategies = strategies;
}
public void executePayment(String type, BigDecimal amount) {
strategies.stream()
.filter(s -> s.supports(type))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Unsupported payment type"))
.processPayment(amount);
}
}
四、Spring生态中的进阶实现
4.1 策略自动注册
@Component
public class StrategyFactory implements ApplicationContextAware {
private Map<String, PaymentStrategy> strategyMap = new ConcurrentHashMap<>();
@Override
public void setApplicationContext(ApplicationContext context) {
context.getBeansOfType(PaymentStrategy.class)
.values()
.forEach(strategy -> strategyMap.put(strategy.getType(), strategy));
}
public PaymentStrategy getStrategy(String type) {
return Optional.ofNullable(strategyMap.get(type))
.orElseThrow(() -> new BusinessException("不支持的支付方式"));
}
}
4.2 策略模式+工厂模式组合
public class PaymentStrategyFactory {
private static final Map<String, PaymentStrategy> strategies = new HashMap<>();
static {
strategies.put("ALIPAY", new AlipayStrategy());
strategies.put("WECHAT", new WechatPayStrategy());
// 自动注册其他策略
}
public static PaymentStrategy getStrategy(String type) {
return Optional.ofNullable(strategies.get(type))
.orElseThrow(IllegalArgumentException::new);
}
}
五、策略模式VS其他模式
模式 | 适用场景 | 复杂度 | 扩展性 |
---|---|---|---|
策略模式 | 算法替换 | 中 | ★★★★ |
工厂模式 | 对象创建 | 低 | ★★★ |
模板方法模式 | 算法框架固定 | 中 | ★★ |
责任链模式 | 多个处理器按顺序处理 | 高 | ★★★★ |
六、最佳实践与注意事项
- 策略粒度控制:单个策略类不应超过300行代码
- 无状态设计:策略类建议设计为无状态,必要时通过上下文传递参数
- 组合使用:与工厂模式、枚举、Spring IOC容器结合使用
- 避免过度设计:简单条件判断(<3个分支)无需使用策略模式
七、性能优化方案
- 策略缓存:使用ConcurrentHashMap缓存策略实例
- 并行处理:对支持并行的策略使用并行流处理
strategies.parallelStream()
.filter(s -> s.supports(type))
.findFirst()
.ifPresent(s -> s.processPayment(amount));
八、实际应用场景
- 电商平台的支付系统
- 风控系统的规则引擎
- 物流系统的运费计算
- 营销活动的优惠计算
- 数据导出格式处理
总结
通过策略模式的改造,我们的支付处理代码:
- 代码量减少60%
- 单元测试覆盖率从45%提升到85%
- 新增支付方式的开发时间从2天缩短到2小时
- 系统扩展成本降低90%
// 最终调用方式
public void processPayment(String type, BigDecimal amount) {
PaymentStrategy strategy = PaymentStrategyFactory.getStrategy(type);
strategy.processPayment(amount);
}
策略模式不是银弹,但确实是消灭复杂if-else的利器。当你的代码中出现以下信号时,就是时候考虑策略模式了:
✅ 相同类型的多个条件分支
✅ 频繁修改的条件逻辑
✅ 需要动态切换算法
✅ 系统存在多种相似处理流程