设计模式胡咧咧之策略工厂实现导入导出

news/2025/2/21 18:35:28/

策略模式(Strategy Pattern)

定义:

定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。

本质:

分离算法,选择实现

应用场景

何时使用

一个系统有许多类,而区分他们的只是他们直接的行为时

优点

开闭原则
避免使用多重条件判断
扩展性良好,增加一个策略只需要实现接口即可

缺点

策略类数量会增多,复用可能性很小
所有策略类都需要对外暴露

场景

多个类,只有算法或行为上稍有不同的场景
算法需要自由切换的场景
需要屏蔽算法规则

实例举例

导入导出
出行方式:自行车、汽车等,每一种出行方式都是一个策略
商场促销方式,打折、满减等
Java LayoutManager 布局管理器

策略模式实现导入/导出

背景:最近在做excle的导入导出,大概10个导出,3个导入。共用的同一个记录表。思来想去用策略+简单工厂模式去除if else if …,以便更好的拓展和维护。
1.定义一个导入接口:
在这里插入图片描述2.创建一个策略工厂:

	@Resourceprivate Map<String, TaskExportHandleService> taskHandleServiceMap;

3.策略枚举:

@Getter
public enum TaskTypeEnum {/*** 任务类型枚举*/DAILY(1, "日常检查"),SPECIAL(2, "专项检查"),ENTERPRISE(3, "企业自查"),;private final Integer code;private final String desc;TaskTypeEnum(int code, String desc) {this.code = code;this.desc = desc;}public static TaskTypeEnum toEnum(int id) {return Arrays.stream(values()).filter(area -> area.getCode().equals(id)).findFirst().orElse(null);}
}

4.实现接口:

@Service("ENTERPRISE")
@Slf4j
public class EnterpriseTaskExportHandleServiceImpl implements TaskExportHandleService {@Overridepublic Long saveRecord(Map<String, Object> paramMap, String operator) {log.info("------------------------");log.info("执行任务:{}", TaskTypeEnum.ENTERPRISE.getDesc());log.info("保存记录文件,状态置为处理中");return 0L;}@Async("TaskExport")@Overridepublic void exportFile(Map<String, Object> paramMap, Long recordId, EpUser currentUser) {log.info("异步处理导出文件ing");log.info("更新到文件记录ing");log.info("------------------------");}
}@Service("DAILY")
@Slf4j
public class DailyTaskExportHandleServiceImpl implements TaskExportHandleService {@Overridepublic Long saveRecord(Map<String, Object> paramMap, String operator) {log.info("------------------------");log.info("执行任务:{}", TaskTypeEnum.DAILY.getDesc());log.info("保存记录文件,状态置为处理中");return 0L;}@Async("TaskExport")@Overridepublic void exportFile(Map<String, Object> paramMap, Long recordId, EpUser currentUser) {log.info("异步处理导出文件ing");log.info("更新到文件记录ing");log.info("------------------------");}
}@Service("SPECIAL")
@Slf4j
public class SpecialTaskExportHandleServiceImpl implements TaskExportHandleService {@Overridepublic Long saveRecord(Map<String, Object> paramMap, String operator) {log.info("------------------------");log.info("执行任务:{}", TaskTypeEnum.SPECIAL.getDesc());log.info("保存记录文件,状态置为处理中");return 0L;}@Async("TaskExport")@Overridepublic void exportFile(Map<String, Object> paramMap, Long recordId, EpUser currentUser) {log.info("异步处理导出文件ing");log.info("更新到文件记录ing");log.info("------------------------");}
}

5.1controller 实现:

@RestController
@RequestMapping("/demo")
//@RequiredArgsConstructor 需要final
@AllArgsConstructor
@Anonymous
@Slf4j
public class TaskController {private final List<TaskExportHandler> exportHandlers;private final DefaultExportHandler defaultExportHandler;@PostMapping("/export")public Result<String> list(@RequestBody TaskExportReq req) {exportHandlers.stream().filter(fileHandler ->fileHandler.support(req.getBusinessType())).findFirst().orElse(defaultExportHandler).exportFile(req.getBusinessType(),new EpUser(), req.getParamMap());return Result.success(null);}
}

5.2导出文件req

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("导出文件req")
public class TaskExportReq {@ApiModelProperty(value = "操作类型枚举 TaskTypeEnum")private Integer businessType;@ApiModelProperty(value = "查询参数")private Map<String, Object> paramMap;}

6.1方便维护,编写任务导出Handler

@Component
public abstract class TaskExportHandler {@Resourceprivate Map<String, TaskExportHandleService> taskHandleServiceMap;public void exportFile(Integer businessType, EpUser currentUser, Map<String, Object> paramMap) {// 匹配处理器TaskExportHandleService taskExportHandleService = matchExportService(businessType);// 保存记录-调用保存文件Long recordId = taskExportHandleService.saveRecord(paramMap, currentUser.getName());// 异步执行导出taskExportHandleService.exportFile(paramMap, recordId, currentUser);}/*** 匹配业务类型对应的导出处理器*/private TaskExportHandleService matchExportService(Integer businessType) {TaskTypeEnum businessTypeEnum = TaskTypeEnum.toEnum(businessType);if (Objects.isNull(businessTypeEnum) || Objects.isNull(taskHandleServiceMap.get(businessTypeEnum.name()))) {throw new ServiceException("不支持的文件操作类型");}return taskHandleServiceMap.get(businessTypeEnum.name());}public Boolean support(Integer businessType) {return Boolean.FALSE;}
}

6.2默认任务Handler

@Component
public class DefaultExportHandler extends TaskExportHandler {}

7运行效果:
在这里插入图片描述


http://www.ppmy.cn/news/1423591.html

相关文章

户外公园亲子实景剧本杀小程序闯关游戏系统开发搭建

开发一个户外公园亲子实景剧本杀小程序闯关游戏系统需要考虑以下几个步骤&#xff1a; 1. 设计游戏场景和剧本&#xff1a;需要设计一系列户外公园的实景场景&#xff0c;并根据每个场景的故事情节设计剧本。需要考虑故事情节的复杂程度和互动性&#xff0c;确保游戏过程的趣味…

SQL基础入门

SQL&#xff08;结构化查询语言&#xff09;是用于管理关系型数据库的标准语言&#xff0c;主要用于在数据库中查询、插入、更新和修改数据。 一些基本SQL知识点包括&#xff1a; 数据类型&#xff1a;每个数据库表的列都需要一个数据类型。一些常见的SQL数据类型包括&#xf…

RIME-SVM,基于RIME寒冰优化算法优化SVM支持向量机回归预测 (多输入单输出)-附代码

支持向量机&#xff08;SVM&#xff09; 支持向量机&#xff08;SVM&#xff09;是一种广泛用于分类和回归的强大监督学习算法。在回归任务中&#xff0c;特别是在SVM被用作支持向量回归&#xff08;SVR&#xff09;时&#xff0c;目标是找到一个函数&#xff0c;这个函数在给…

Linux命令学习—Apache 服务器(上)

1.1、http 服务原理 http 超文本传送协议 80 端口 https 安全的超文本传输协议 443 端口 基于 C/S(客户端/服务端)模型 协议流程&#xff1a; 连接&#xff1a;客户端与服务端建立连接 请求&#xff1a;客户端向服务端发送请求 应答&#xff1a;服务端响应&#xff0c;将结果…

前后端交互实例(javaweb05)

文章开始前,先给大家看一张图,这是黑马javaweb-day05请求响应实例,也是第一个实现了前后端交互,这是我画的流程图,搞懂了前后端是如何交互的.(文件的所有路径不能出现中文,否则会报错,这个我暂时不知道该怎么解决). 那么这里面涉及到的东西,除了emp.html这是已经提供了的前端页…

C++ - STL详解— string类(二)

对于STL的学习&#xff0c;大家更多的是去查官方文档&#xff0c;我觉得这是一种很高效和系统的学习&#xff0c;所以下面我会把对应的文档内容都给大家翻译出来&#xff0c;以方便大家学习STL&#xff0c;共勉进步&#xff0c;加油加油&#xff01;&#xff01; 函数名称功能…

Es6Proxy基础用法

proxy可以理解成为在目标对象之前设置一层拦截&#xff0c;每当对该对象进行访问&#xff0c;都会经过这层拦截&#xff0c;这种机制可以对外界的访问进行过滤和改写。 proxy一词意为代理&#xff0c;用在这里表示由它代理某些操作&#xff0c;可以翻译为代理器。 var obj n…

jenkins 部署 vue 项目

jenkins 部署 vue 项目 环境 系统&#xff1a;CentOS7.9 Jenkins&#xff1a;最新LTS版本 nginx: 1.24.x gitLab: 打包机&#xff1a;jenkins所在服务器 目标机器&#xff1a;nginx所在服务器 jenkins部署配置 关键脚本 #node -v #已经安装node_module就无需执行install安…