Java 设计模式之-策略模式
策略模式结构组成
- Strategy:抽象策略类,一般为接口或者策略类
- ConcreteStrategy:具体算法实现策略类
- Context:环境或者上下文类,用于统一执行具体策略
其实以上三部分用白话文来解释就是: 需要一个接口和策略进行规范和约束接口和方法,这时需要一些具体的实现算法类去继承或者实现刚刚的接口和策略,最后通过一个环境或者上下文,也可以叫做工厂根据类型进行调用具体的算法!
使用场景
- 避免冗长的 if-else 或 switch 分支判断
- 需要动态地在几种算法中选择一种
- 对客户隐藏具体策略 (算法) 的实现细节,彼此完全独立,扩展其余不受影响
具体场景一般为:
- 支付方式选择
- 打折、满减方式选择
- 根据类型调用不同的系统
优缺点:
优点:
- 扩展性好
- 符合开闭原则
- 符合单一职责原则
- 可读性好
- 便于维护
- 避免多层判断
缺点:
- 策略过多,导致策略类
- 对新手读代码不友好
小栗子
春夏秋冬四季需要做不同的事情来演示一下策略模式的使用方案; 需求是: 如果是春天,就要去放风筝 如果是夏天,就要去游泳 如果是秋天,就要去看枫叶 如果是冬天,就要去打雪仗 没有使用策略模式的话, 肯定就是 if-if else进行实现!
If-Else 实现
public static void main(String[]args){
System.out.println(todoSomeThing("冬天"));
}
public static String todoSomeThing(String seasons){
if("春天".equals(seasons)){
return seasons+"来了!我们一起去放风筝吧!";
}else if("夏天".equals(seasons)){
return seasons+"来了!我们一起去游泳吧!";
}else if("秋天".equals(seasons)){
return seasons+"来了!我们一起去放看枫叶吧!";
}else if("冬天".equals(seasons)){
return seasons+"来了!我们一起去打雪仗吧!";
}else{
return"不知道干什么";
}
}
策略模式实现
抽象策略
/**
* 四季策略
*/
public interface SeasonsStrategy {
/**
* 根据季节去执行不同的方案
* @param seasons
* @return
*/
String execute(String seasons);
}
具体算法实现策略类
春天
/***
* 春季具体实现
*/
// 指定容器的名称,不指定默认为类名称首字母小写
@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 + "来了!我们一起去打雪仗吧!";
}
}
环境或者上下文类
/**
* 环境或者上下文类,用于统一执行具体策略
*/
@Component
public class SeasonsFactory {
/**
* Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类
*/
@Autowired
private Map<String, SeasonsStrategy> seasonsMap;
/**
* 处理四季统一入口方法
*
* @param seasons
* @param beanName
* @return
*/
public String handle(String seasons, String beanName) {
// 根据bean的名称获取对应的算法处理类
SeasonsStrategy seasonsStrategy = seasonsMap.get(beanName);
String execute = seasonsStrategy.execute(seasons);
return execute;
}
}
测试
@RestController
public class TestController {
@Autowired
private SeasonsFactory seasonsFactory;
@GetMapping("/strategyTest/{seasons}/{beanName}")
public String strategyTest(@PathVariable("seasons") String seasons, @PathVariable("beanName") String beanName) {
String handle = seasonsFactory.handle(seasons, beanName);
return handle;
}
}
文章参考:https://juejin.cn/post/7246409673565716539