工厂+策略模式

news/2024/9/29 15:04:29

一、策略模式概述:

策略模式(又叫政策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;@Beanpublic 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<>();//@AutowiredTrafficType trafficType;@Overridepublic 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 {/*** 查询交通方式编码标识* @return 编码*///方式一TrafficCodeEmun getCode();//方式二String getCode();//方式三、四,去掉getCode()方法/*** 获取交通方式的费用* @return 费用*/Integer getFee();}@Service
public class TrainModeServiceImpl implements TrafficModeService {/*** 获取交通方式编码标识* @return 编码*/@Overridepublic TrafficCodeEmun getCode() {//方式一,利用枚举类型return TrafficCodeEmun.TRAIN;}@Overridepublic String getCode() {//方式二,去掉不用枚举类型,直接设置返回值return "TRAIN";}//方式三、四,直接去掉getCode()方法和枚举类型/*** 获取交通方式的费用* @return 费用*/@Overridepublic Integer getFee() {return 5000;}}@Service
public class BusModeServiceImpl implements TrafficModeService {/*** 查询交通方式编码* @return 编码*/@Overridepublic String getCode() {return "bus";}/*** 查询交通方式的费用,单位:分* @return 费用*/@Overridepublic 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容器中的标识

方式四:没有枚举类,但是使用了配置文件,新增一种出行方式,只需增加一个策略类,以及在配置文件中增加内容即可

增加枚举类也可以达到无侵入业务代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/66185.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

时间格式化标签说明

时间格式化标签和PHP时间格式化语法一致,可以使用不同的字母代替,中间可以穿插任意字符。常见的格式包括:Y:四位数的年份 m:两位数的月份 d:两位数的日期 H:两位数的小时 i:两位数的分钟 s:两位数的秒示例格式 以下是一些示例格式:Y-m-d:2023-09-15 Y/m/d:2023/09/…

PbootCMS模板添加栏目提示:该内容栏目编号已经存在,不能再使用

当你在PbootCMS中添加栏目时,如果提示“该内容栏目编号已经存在,不能再使用”,这通常是因为数据库中的栏目编号(scode)已经存在重复。解决这个问题的方法是修改数据库中对应的栏目编号。 解决办法 1. 使用数据库管理工具 推荐使用数据库管理工具(如Navicat Premium)来管…

大json字符串处理

背景: 当从API获取数据或与其他系统交换信息时。有时json字符串可能会非常庞大,以至于读取到内存中会导致内存溢出或者性能问题 流式处理: 如果JSON字符串过大,不适合一次性加载到内存中,可以考虑使用流式处理。例如,使用Jackson库的JsonParser,可以逐行解析JSON,从而避…

一文读懂 Git fetch 和 Git pull 的终极区别(带实验结果)

Git pull 是一个 Git 命令用来同时执行 git fetch 和 git merge。本文分享了这两个命令的区别和用法。 Git 命令是非常流行的,尤其是在分布式版本控制系统中,可以对远端的仓库进行同步。开发者需要根据项目实际所需来选择合适的命令。在本文章中,我们将解释 git fetch 和 g…

pbootcms的图片裁剪确保无论图片是横图还是竖图,都能居中裁剪

解决方案找到裁剪缩略图的方法:文件位置:/core/function/file.php 搜索:function cut_img,大约在447行优化cut_img方法:实现居中裁剪功能优化代码 以下是优化后的cut_img函数代码: // 剪切图片 function cut_img($src_image, $out_image = null, int $new_width = null, …

Online DDL

MySQL在线DDL特性提供了即时支持instant 、copy方式,还有原表in-place方式。有些过程中也允许并发DML。 语法:ALTER TABLE tbl_name , alter_option: {...}, ALGORITHM [=] {DEFAULT | INSTANT | INPLACE | COPY} LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}为了避免在执…

pbootcms提示提交失败,请使用POST方式提交

在PbootCMS中,如果你在模板在线留言功能中遇到“提交失败,请使用POST方式提交!”的错误,通常是因为URL名称使用了系统保留的关键字。为了避免这类问题,可以遵循以下建议: 1. 系统保留关键字 PbootCMS系统中有一些保留的关键字,这些关键字不能用作URL名称。以下是一些常见…

ElementUI中实现el-table表格列宽自适应,列根据内容自动撑满,内容不换行

一、概述 在表格宽度固定时,实现内容不换行,表格自动显示滚动条 当前显示效果: 期望实现效果: 二、实现思路 遍历表格数组,每次都构建一个隐藏的span元素,获取该元素的宽度,对比保存最大值 代码如下:```typescript /*** 表格列宽自适应* @param prop 属性* @param reco…