Spring Boot 整合策略模式
一、前言
策略模式是一种在实际开发中应用广泛且面试中常见的话题。作为代码重构和优化的利器,它能有效提升代码的扩展性和可维护性。本文通过一个实际场景,展示如何在 Spring Boot 中实现策略模式,并分享其企业级应用的心得。
二、策略模式基础知识
1. 什么是策略模式
策略模式(Strategy Design Pattern)是 GoF 设计模式之一,其定义为:
定义一组算法,将每个算法封装起来,使它们可以互相替换,并且使算法的变化独立于使用它们的客户端代码。
通俗来讲,策略模式将一组算法抽象成接口,具体实现为独立类,通过上下文类动态选择执行某个具体策略。
2. 策略模式的结构组成
Strategy
(抽象策略类):接口或抽象类,定义具体策略的约定方法。ConcreteStrategy
(具体策略类):实现抽象策略类的具体算法。Context
(上下文类):维护对抽象策略的引用,用于动态调用具体策略。
简单理解:策略模式需要一个接口来规范算法行为,一些实现类提供具体算法,上下文类负责根据条件选择调用合适的算法。
3. 策略模式的使用场景
适用场景
- 替代冗长的
if-else
或switch
分支判断。 - 需要动态选择不同算法。
- 需要对外隐藏具体策略的实现细节,保持策略独立扩展。
常见应用
- 支付方式选择(如微信支付、支付宝、银联支付)。
- 优惠策略选择(满减、折扣、积分抵扣)。
- 根据条件调用不同子系统。
4. 策略模式的优缺点
优点
- 扩展性强:新增策略无需修改现有代码,符合 开闭原则。
- 单一职责原则:每个策略类只处理自己的业务逻辑。
- 可读性强:消除了复杂的分支判断。
- 维护性高:算法间相互独立。
缺点
- 策略类数量增多,可能导致系统复杂度上升。
- 初学者可能对设计模式不熟悉,阅读理解难度增加。
三、策略模式在 Spring Boot 中的应用
示例需求
根据四季执行不同的活动:
- 春天:放风筝
- 夏天:游泳
- 秋天:看枫叶
- 冬天:打雪仗
1. 定义策略接口
/**
* 四季策略接口
*/
public interface SeasonsStrategy {
/**
* 执行策略方法
* @param seasons 当前季节
* @return 执行结果
*/
String execute(String seasons);
}
2. 具体策略实现
春季策略
@Component("spring")
public class SpringStrategy implements SeasonsStrategy {
@Override
public String execute(String seasons) {
return seasons + "来了!我们一起去放风筝吧!";
}
}
夏季策略
@Component("summer")
public class SummerStrategy implements SeasonsStrategy {
@Override
public String execute(String seasons) {
return seasons + "来了!我们一起去游泳吧!";
}
}
秋季策略
@Component("autumn")
public class AutumnStrategy implements SeasonsStrategy {
@Override
public String execute(String seasons) {
return seasons + "来了!我们一起去看枫叶吧!";
}
}
冬季策略
@Component("winter")
public class WinterStrategy implements SeasonsStrategy {
@Override
public String execute(String seasons) {
return seasons + "来了!我们一起去打雪仗吧!";
}
}
3. 定义上下文工厂
通过 Spring 自动注入策略实现类到 Map 中,根据 beanName
动态选择策略。
@Component
public class SeasonsFactory {
@Autowired
private Map<String, SeasonsStrategy> seasonsMap;
/**
* 根据 beanName 执行对应的策略
* @param seasons 当前季节
* @param beanName 策略名称
* @return 执行结果
*/
public String handle(String seasons, String beanName) {
SeasonsStrategy strategy = seasonsMap.get(beanName);
if (strategy == null) {
throw new IllegalArgumentException("策略不存在:" + beanName);
}
return strategy.execute(seasons);
}
}
4. 控制层调用
定义 API,接受季节和策略名称作为参数,调用对应策略。
@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private SeasonsFactory seasonsFactory;
@GetMapping("/strategyTest/{seasons}/{beanName}")
public Result strategyTest(@PathVariable String seasons, @PathVariable String beanName) {
String result = seasonsFactory.handle(seasons, beanName);
return Result.success(result);
}
}
5. 测试接口
请求示例:
GET http://localhost:8087/test/strategyTest/春天/spring
返回结果:春天来了!我们一起去放风筝吧!
GET http://localhost:8087/test/strategyTest/夏天/summer
返回结果:夏天来了!我们一起去游泳吧!
四、总结
- 策略模式特点:通过封装算法、动态选择实现,消除复杂分支逻辑,提升代码扩展性。
- 适用场景:避免冗长判断逻辑,便于动态扩展策略。
- 实践经验:在业务开发中使用设计模式应视场景而定,避免过度设计。
策略模式虽然强大,但需要权衡项目复杂度和维护成本,确保其带来的好处超出引入成本。
评论区