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

策略模式(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.mfbz.cn/a/556333.html

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

相关文章

【赛题】2024年“华中杯”数模竞赛赛题发布

2024年"华中杯"数学建模网络挑战赛——正式开赛&#xff01;&#xff01;&#xff01; 赛题已发布&#xff0c;后续无偿分享各题的解题思路、参考文献&#xff0c;帮助大家最快时间&#xff0c;选择最适合是自己的赛题。祝大家都能取得一个好成绩&#xff0c;加油&a…

Python数据可视化:散点图matplotlib.pyplot.scatter()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 Python数据可视化&#xff1a; 散点图 matplotlib.pyplot.scatter() 请问关于以下代码表述错误的选项是&#xff1f; import matplotlib.pyplot as plt x [1, 2, 3, 4, 5] y [2, 3, 5, 7,…

认识一下RAG

1.RAG技术背景与挑战 2.RAG的核心概念 3.RAG的工作流程与架构 4.RAG的优化方法 RAG的提出 •Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks是一篇重要的论文(2020年5月) •REALM: Retrieval-Augmented Language Model Pre-Training (2020)就将BERT预训练模…

libVLC Ubuntu编译详解

1.简介 有时候&#xff0c;windows上开发不满足项目需求&#xff0c;需要移植到linux上&#xff0c;不得不自行编译libvlc&#xff0c;编译libvlc相对而言稍微麻烦一点。 我使用的操作系统&#xff1a;Ubuntu20.04 查看系统命令lsb_release -a libvlc版本&#xff1a; 3.0.1…

CSS导读 (CSS的三大特性 上)

&#xff08;大家好&#xff0c;今天我们将继续来学习CSS的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 五、CSS的三大特性 5.1 层叠性 5.2 继承性 5.2.1 行高的继承 5.3 优先级 小练习 五、CSS的三大特性 …

Goland远程连接Linux进行项目开发

文章目录 1、Linux上安装go的环境&#xff12;、配置远程连接3、其他配置入口 跑新项目&#xff0c;有个confluent-Kafka-go的依赖在Windows上编译不通过&#xff0c;报错信息&#xff1a; undefined reference to __imp__xxx似乎是这个依赖在Windows上不支持&#xff0c;选择让…

数据库设计的三范式

简单来说就是&#xff1a;原子性、唯一性、独立性 后一范式都是在前一范式已经满足的情况进行附加的内容 第一范式&#xff08;1NF&#xff09;&#xff1a;原子性 存储的数据应不可再分。 不满足原子性&#xff1a; 满足原子性&#xff1a; 第二范式&#xff08;2NF&#xf…

历史遗留问题1-Oracle Mysql如何存储数据、索引

在学习到Oracle redo和undo时&#xff0c;涉及到很多存储结构的知识&#xff0c;但是网上的教程都不是很详细&#xff0c;就去复习了一下mysql&#xff0c;感觉是不是开源的问题&#xff0c;Mysql的社区和知识沉淀远高于Oracle&#xff0c; 对于初学者很友好&#xff0c;我想请…

生成人工智能体:人类行为的交互式模拟论文与源码架构解析(5)——可控评估端到端评估

最后完结篇,文末有测试中发现的有趣现象,并附上了相关资料链接~ 5.可控评估 分两个阶段评估生成代理。我们从一个更加严格控制的评估开始,单独评估代理的响应,以了解它们是否在狭义上定义的上下文中产生可信的行为。然后,在我们对代理社区进行为期两天的端到端分析中,我…

初始C++

1. C关键字(C98) C总计63个关键字&#xff0c; C语言32个关键字 ps&#xff1a;下面我们只是看一下C有多少关键字&#xff0c;不对关键字进行具体的讲解。后面我们学到以后再 细讲。 2. 命名空间 在C/C中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;…

llama-factory SFT系列教程 (三),chatglm3-6B 大模型命名实体识别实战

文章列表&#xff1a; llama-factory SFT系列教程 (一)&#xff0c;大模型 API 部署与使用llama-factory SFT系列教程 (二)&#xff0c;大模型在自定义数据集 lora 训练与部署 llama-factory SFT系列教程 (三)&#xff0c;chatglm3-6B 命名实体识别实战 简介 利用 llama-fa…

opencv | 编译缺失ippicv相关文件解决方案

1.执行cmake后&#xff0c;查看控制台输出信息 ~/VM_data/opencv-4.9.0$ cd buile_temp ~/VM_data/opencv-4.9.0/buile_temp$ cmake ..2.去浏览器打开链接&#xff0c;下载对应的压缩包&#xff0c;解压到 路径&#xff1a;/3rdparty/ippicv/

Ubuntu 安装 wine

本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 如果你使用 Ubuntu 系统&#xff0c;而有些软件只在 Windows 上运行&#xff0c;例如&#xff1a;PotPlayer&#xff0c;那么该如何在 Ubuntu 系统中使用到这些 Windows 的软件呢&#xff1f;答案是安装 wine。 简单的安装步骤如…

在Windows安装R语言

直接安装R语言软件 下载网址&#xff1a;R: The R Project for Statistical Computing 下载点击install R for the first time 通过Anaconda下载RStudio 提前下载好Anaconda 点击Anaconda Navigate 点击RStudio的Install下载就好了

Python:可迭代对象与迭代器

相关阅读 Pythonhttps://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 根据Python官方文档&#xff0c;可迭代对象(iterable)是“一种能够逐个返回其成员项的对象”。具体来说&#xff0c;这种对象要么定义了一个返回迭代器(iterator)的魔术…

如何实现Windows RDP 远程桌面异地跨网连接

Windows RDP远程桌面的应用非常广泛。远程桌面协议(RDP)是一个多通道(multi-channel)的协议&#xff0c;让使用者(所在计算机称为用户端或本地计算机)连上提供微软终端机服务的计算机(称为服务端或远程计算机)。大部分的Windows版本都有用户端所需软件&#xff0c;有些其他操作…

太阳能路灯光伏板的朝向设计问题

题目&#xff1a;太阳能路灯光伏板的朝向设计问题 难度对标几乎每一年的国赛A题。 QQ群&#xff1a;592697532 公众号&#xff1a;川川菜鸟 文章目录 背景问题问题一问题二问题三 题目解读相关公式&#xff08;必备&#xff09;太阳辐射的计算光伏板接收的辐射光学效率大 气透…

数据结构(顺序栈

目录 1. 讲解&#xff1a;2. C代码实现&#xff1a;小结&#xff1a; 1. 讲解&#xff1a; 用顺序的物理结构&#xff08;数组&#xff09;存储栈这个数据结构&#xff0c;实现栈的创建、销毁、增删查、判空。 top指针的指向位置有两种实现方法&#xff1a;一个是指向栈顶元素…

云服务器部署Springboot项目

前端项目打包 修改ip地址 在控制台输入npm run build:prod 会产生dist文件 将dist文件中的内容移动至/usr/local/nginx/html目录下 后端项目打包 修改ip地址 执行clean操作 执行install操作 将生成的target文件中的jar包移动至/usr/local/src目录下 启动 注意⚠️&#xff…

前沿论文 | LLM推理性能优化最佳实践

原文&#xff1a;安全验证 - 知乎​ 来源 题目&#xff1a;LLM Inference Performance Engineering: Best Practices 地址&#xff1a;https://www.databricks.com/blog/llm-inference-performance-engineering-best-practices 在这篇博文中&#xff0c;MosaicML工程团队分析了…