一、策略模式概述:
策略模式(又叫政策Policy模式),属于对象行为模式下的:Strategy类提供了可插入式(Pluggable)算法的实现方案。
策略模式的定义-意图:定义一系列算法,将每一个算法封装起来,并让它们互相替换。策略模式让算法可以独立于使用它的客户变化。
二、模式策略的优缺点:
优点:
1.提供了对开闭(开时针对扩展功能是开放的,闭对修改功能是关闭的)原则的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为;
2.提供了管理相关的算法族的办法;
3.提供了一种可以替换继承关系的办法;
4.可以避免多重条件选择语句;
5.提供了一种算法的复用机制,不同环境类可以方便地复用策略类。(单一职责)
缺点:
1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类; 2.将造成系统产生很多具体策略类; 3.无法同时在客户端使用多个策略类。
适用环境:
1.一种系统需要动态地在几种算法中选择一种; 2.避免使用难以维护的多重条件选择语句; 3.不希望客户端知道复杂的、与算法相关的数据结构,提高算法的保密性与安全。
四种不同的实现方式:
枚举类,方式一
@AllArgsConstructor
public enum TrafficCodeEmun {
TRAIN("TRAIN","火车"),
BUS("BUS","大巴");
private final String code;
private final String desc;
}
|
方式四,利用配置文件,保存读取配置文件的结果
@Configuration
public class TrafficType {
@Value("#{${trafficType:{}}}")
private Map<String, String> trafficType;
@Bean
public Map<String, String> getTrafficType() {
return trafficType;
}
}
#方式四,配置文件yml文件中的内容
trafficType: "{
'train': 'trainModeServiceImpl',
'bus': 'busModeServiceImpl'
}"
|
核心工厂类
@Component
@Slf4j
public class TrafficModeFactory implements ApplicationContextAware {
public static final ConcurrentHashMap<TrafficCodeEmun, TrafficModeService> TRAFFIC_BEAN_MAP = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<String, TrafficModeService> TRAFFIC_BEAN_MAP = new ConcurrentHashMap<>();
TrafficType trafficType;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, TrafficModeService> map = applicationContext.getBeansOfType(TrafficModeService.class);
map.forEach((key, value) -> TRAFFIC_BEAN_MAP.put(value.getCode(), value));
map.forEach((key, value) -> TRAFFIC_BEAN_MAP.put(key, value));
trafficType.getTrafficType().forEach((key, value) -> {
TRAFFIC_BEAN_MAP.put(key, (TrafficModeService) applicationContext.getBean(value));
});
}
public static <T extends TrafficModeService> T getTrafficMode(TrafficCodeEmun code) {
return (T) TRAFFIC_BEAN_MAP.get(code);
}
public static <T extends TrafficModeService> T getTrafficMode(String code) {
return (T) TRAFFIC_BEAN_MAP.get(code);
}
}
|
策略接口,策略实现类
public interface TrafficModeService {
TrafficCodeEmun getCode();
String getCode();
Integer getFee();
}
@Service
public class TrainModeServiceImpl implements TrafficModeService {
@Override
public TrafficCodeEmun getCode() {
return TrafficCodeEmun.TRAIN;
}
@Override
public String getCode() {
return "TRAIN";
}
@Override
public Integer getFee() {
return 5000;
}
}
@Service
public class BusModeServiceImpl implements TrafficModeService {
@Override
public String getCode() {
return "bus";
}
@Override
public Integer getFee() {
return 6000;
}
}
@Test
public void testParttern() {
Integer fee = TrafficModeFactory.getTrafficMode(TrafficCodeEmun.TRAIN).getFee();
Integer fee = TrafficModeFactory.getTrafficMode("train").getFee();
Integer fee = TrafficModeFactory.getTrafficMode("trainModeServiceImpl").getFee();
Integer fee = TrafficModeFactory.getTrafficMode("train").getFee();
System.out.println(fee);
}
|
策略模式,本身就是要求使用者知道都有哪些策略类才行,扩展时可通过抽象类实现策略接口,然后策略类继承抽象类
方式一:有枚举类,新增一种出行方式需要增加一个策略类,修改枚举类型
方式二:没有枚举类,新增一种出行方式,只需增加一个策略类,设置名称标识,不需要枚举类型,也不需要修改枚举类型
方式三:没有枚举类,新增一种出行方式,只需增加一个策略类,只是传参的时候需要传策略实现类在spring容器中的标识
方式四:没有枚举类,但是使用了配置文件,新增一种出行方式,只需增加一个策略类,以及在配置文件中增加内容即可
增加枚举类也可以达到无侵入业务代码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现