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

news2024/11/26 18:48:05

策略模式(Strategy Pattern)

定义:

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

本质:

分离算法,选择实现

应用场景

何时使用

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

优点

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

缺点

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

场景

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

实例举例

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

策略模式实现导入/导出

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

	@Resource
    private 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 {
    @Override
    public Long saveRecord(Map<String, Object> paramMap, String operator) {
        log.info("------------------------");
        log.info("执行任务:{}", TaskTypeEnum.ENTERPRISE.getDesc());
        log.info("保存记录文件,状态置为处理中");
        return 0L;
    }

    @Async("TaskExport")
    @Override
    public 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 {
    @Override
    public Long saveRecord(Map<String, Object> paramMap, String operator) {
        log.info("------------------------");
        log.info("执行任务:{}", TaskTypeEnum.DAILY.getDesc());
        log.info("保存记录文件,状态置为处理中");
        return 0L;
    }

    @Async("TaskExport")
    @Override
    public 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 {
    @Override
    public Long saveRecord(Map<String, Object> paramMap, String operator) {
        log.info("------------------------");
        log.info("执行任务:{}", TaskTypeEnum.SPECIAL.getDesc());
        log.info("保存记录文件,状态置为处理中");
        return 0L;
    }

    @Async("TaskExport")
    @Override
    public 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 {
    @Resource
    private 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.coloradmin.cn/o/1604250.html

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

相关文章

Python与数据库交互的最佳实践

Python作为一种强大且易于学习的编程语言&#xff0c;在数据处理和应用程序开发方面具有广泛的应用。在构建涉及数据存储和检索的应用程序时&#xff0c;Python与数据库的交互成为关键的一环。本文将深入探讨Python与数据库交互的最佳实践&#xff0c;帮助读者更好地理解和应用…

软考 系统架构设计师系列知识点之大数据设计理论与实践(10)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之大数据设计理论与实践&#xff08;9&#xff09; 所属章节&#xff1a; 第19章. 大数据架构设计理论与实践 第3节 Lambda架构 19.3.5 Lambda架构优缺点 1. 优点 &#xff08;1&#xff09;容错性好 Lambda架构为大数…

你信不信,五分钟快速学习Nginx

Nginx是什么&#xff1f; Nginx 是一个高性能的HTTP和反向代理服务器。它是由俄罗斯程序员Igor Sysoev开发的&#xff0c;最初是为了解决俄罗斯大型的门户网站的高流量问题。 说到反向代理&#xff0c;那么有没有正向代理呢&#xff1f; 正向代理&#xff1a;客户端非常明确要…

二叉树的中序遍历 - LeetCode 热题 36

大家好&#xff01;我是曾续缘&#x1f603; 今天是《LeetCode 热题 100》系列 发车第 36 天 二叉树第 1 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输…

考研数学|《1800》《660》《880》如何选择和搭配?(附资料分享)

直接说结论&#xff1a;基础不好先做1800、强化之前660&#xff0c;强化可选880/1000题。 首先&#xff0c;传统习题册存在的一个问题是题量较大&#xff0c;但难度波动较大。《汤家凤1800》和《张宇1000》题量庞大&#xff0c;但有些题目难度不够平衡&#xff0c;有些过于简单…

图神经网络推荐系统

链接&#xff08;何向南教授&#xff09;&#xff1a;https://hexiangnan.github.io/papers/wsdm22-tutorial-proposal.pdf 摘要&#xff1a; 近年来&#xff0c;图神经网络(graph neural network, GNN)以其强大的结构化数据处理能力和对高阶信息的挖掘能力&#xff0c;成为许…

全格式播放器哪个好?分享好用的播放器

全格式播放器哪个好&#xff1f;在数字化时代&#xff0c;全格式播放器的重要性日益凸显。它们凭借强大的兼容性和高效的解码能力&#xff0c;让我们能够轻松应对各种音视频格式的播放需求。无论是观看高清电影、欣赏高品质音乐&#xff0c;还是处理工作中的多媒体文件&#xf…

idea中停止运行Vue

在里面敲入Ctrlc 输入y确定即可。

【Proteus】51单片机对直流电机的控制

直流电机&#xff1a;输出或输入为直流电能的旋转电机。能实现直流电能和机械能互相转换的电机。把它作电动机运行时是直流电动机&#xff0c;电能转换为机械能&#xff1b;作发电机运行时是直流发电机&#xff0c;机 械能转换为电能。 直流电机的控制&#xff1a; 1、方向控制…

中国隧道空间分布

中国隧道空间分布数据&#xff0c;包含2020年全国大部分地区16000余条隧道分布点位数据&#xff0c;数据包括市名称、区县名称、隧道名称和隧道经纬度。数据包含shp和EXCEl两种格式&#xff0c;部分隧道空间位置有偏移。 欢迎大家关注、收藏和留言&#xff0c;如果您想要什么数…

文化=知识+素质!电动车限制多!——早读(逆天打工人爬取热门微信文章解读)

你是一个有文化的人&#xff01; 引言Python 代码第一篇 洞见 一个人有没有文化&#xff0c;就看这五点第二篇 人民日报 来啦 新闻早班车要闻社会政策 结尾 知耻近乎勇 文化教会我们自省 以羞耻心为镜 照见自我 不断向善向上。 引言 绝了 昨天晚上早早上床 10点左右就睡眠模…

【刷题笔记】第八天

文章目录 [928. 尽量减少恶意软件的传播 II](https://leetcode.cn/problems/minimize-malware-spread-ii/)方法1&#xff1a;dfs方法2&#xff1a;并查集 [GCD and LCM](https://vjudge.net.cn/problem/Aizu-0005)[Missing Bigram](https://vjudge.net.cn/problem/CodeForces-1…

三步教你怎么把icloud照片恢复至iphone!

“我手机里面照片被优化后&#xff0c;然后不小心把所有被优化的模糊照片从手机中删除了&#xff0c;但是iCloud还有&#xff0c;我应该怎样把iCloud的照片重新放回手机&#xff1f;谢谢。” 在使用iPhone时&#xff0c;iCloud照片库是一个非常方便的功能&#xff0c;它允许你在…

【SVG】从零开始绘制条形图

效果图 定义背景色和坐标轴颜色 :root {--cord-color: #2be7ca; }body {background-color: #000;}画坐标轴 画X轴 <!-- 坐标轴 --> <g id"cordinate"><!-- x轴 --><line x1"50" y1"600" x2"900" y2"600&q…

博弈论和sg函数

Nim游戏 题目链接&#xff1a;Nim游戏 先说结论&#xff1a;假设n堆石子&#xff0c;石子数分别为a1,a2,a3.....&#xff0c;则当a1^a2^a3^...^an0时先手必败&#xff0c;否则先手必胜。 因为所表示的二进制位必定是成对出现的&#xff0c;根据性质 1 ^ 1 0 &#xff0c;0 …

MyBatis 源码分析 - 缓存原理

MyBatis 源码分析 - 缓存原理 1.简介 在 Web 应用中&#xff0c;缓存是必不可少的组件。通常我们都会用 Redis 或 memcached 等缓存中间件&#xff0c;拦截大量奔向数据库的请求&#xff0c;减轻数据库压力。作为一个重要的组件&#xff0c;MyBatis 自然也在内部提供了相应的…

量子密钥分发系统的设计与实现(二):光路子系统初步讨论

通过上一篇文章&#xff0c;我们对量子密钥分发系统的基本架构、硬件结构以及密钥分发流程进行了初步的总体介绍&#xff0c;从本文开始&#xff0c;我们就基于系统顶层的架构设计&#xff0c;开始从模块到器件&#xff0c;从硬件到软件开始详细讨论QKD系统的设计与实现。本文主…

【转】这些年背过的面试题——网络和操作系统基础篇

转自&#xff1a;阿里巴巴技术质量 阿里云开发者 阿里妹导读 本文是技术人面试系列网络和操作系统基础篇&#xff0c;面试中关于网络和操作系统基础都需要了解哪些内容&#xff1f;一文带你详细了解&#xff0c;欢迎收藏&#xff01; 网络基础 TCP三次握手 三次握手过程&…

陇剑杯 ios 流量分析 CTF writeup

陇剑杯 ios 流量分析 链接&#xff1a;https://pan.baidu.com/s/1KSSXOVNPC5hu_Mf60uKM2A?pwdhaek 提取码&#xff1a;haek目录结构 LearnCTF ├───LogAnalize │ ├───linux简单日志分析 │ │ linux-log_2.zip │ │ │ ├───misc日志分析 │ │…

华为云服务镜像手动更换

操作步骤&#xff1a; 1、进入华为云首页点击云容器引擎CCE&#xff1b; 2、选择你所要更换镜像的环境【这里以dev环境演示】&#xff1b; 3、点击dev环境后选择顶部的命名空间&#xff0c;点击【工作负载】中右侧栏的【升级】按钮&#xff1b; 4、点【更换镜像】选择你在test…