SpringBoot中策略模式+工厂模式业务实例(接口传参-枚举类查询策略映射关系-执行不同策略)规避大量if-else

2023-11-18

场景

设计模式-策略模式在Java中的使用示例:

设计模式-策略模式在Java中的使用示例_java 策略模式示例_霸道流氓气质的博客-CSDN博客

上面讲了策略模式在Java中的使用示例。

下面看一个在SpringBoot中的实际使用示例。

业务场景:

有多个煤矿,信号灯有多个厂家/规则,每个煤矿对应一种信号灯。

需要编写通用接口,根据传递的请求码不同获取到该煤矿对应的信号灯规则,并执行对应的信号灯规则获取数据。

注:

博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主

实现

1、新建信号灯规则接口类

public interface SignalLightRules {

    List<SignalrightDevsDTO> getSignalrightDevsDtoList(String mineApiCode);

}

其中方法getSignalrightDevsDtoList是用来获取信号灯信息。

2、新建厂家1/规则1的实现类

@Component(Constants.SIFANGJI)
public class SiFangJiSignalLightRules implements SignalLightRules{

    @Autowired
    private SNDataUploadServiceImpl snDataUploadService;

    @Autowired
    private BusSignallightControlService busSignallightControlService;

    @Override
    public List<SignalrightDevsDTO> getSignalrightDevsDtoList(String mineApiCode) {
        //获取所有信号灯id
        List<Long> signalLightIdList = busSignallightControlService.selectBusSignallightControlIdList();
        List<SignalrightDevsDTO> signalrightDevsDtoList = snDataUploadService.getSignalrightDevsDtoList(signalLightIdList,mineApiCode);
        return signalrightDevsDtoList;
    }
}

注意这里添加注解

@Component(Constants.SIFANGJI)

并且名称使用了常量类的常量。

附常量类

public class Constants {

    public static final String SIFANGJI = "sifangji";

    public static final String KEERMA = "keerma";

}

然后在具体获取信号灯数据的方法中调用的两个service都是跟本厂家/规则具体业务相关。

3、新建厂家2/规则2的实现类

@Component(Constants.KEERMA)
public class KeErMaSignalLightRules implements SignalLightRules{
    @Override
    public List<SignalrightDevsDTO> getSignalrightDevsDtoList(String mineApiCode) {
        return new ArrayList<>();
    }
}

这里具体业务实现直接返回一个空list。

4、新建信号灯工厂类,用来获取对应的信号灯规则

@Component
public class SignalLightRulesFactory {

    //Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id 即前面@Component注解指定的名称,value值则为对应的策略实现类
    @Autowired
    Map<String,SignalLightRules> signalLightRulesStrategy;

    private static final SignalLightRules DEFAULT_RULES = new SiFangJiSignalLightRules();

    public  SignalLightRules getSignalLightRules(String signalLightKey){
        SignalLightRules signalLightRules = signalLightRulesStrategy.get(signalLightKey);
        return signalLightRules == null?DEFAULT_RULES:signalLightRules;
    }
}

注意这里添加@Component注解,并且在存储规则的map上添加@Autowired,

Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id 即前面@Component注解指定的名称,

value值则为对应的策略实现类。

5、不同的煤矿使用的信号灯规则可能相同也可能不同,所以需要配置一个煤矿与信号灯规则的映射关系的存储。

import com.badao.demo.constant.Constants;
import org.springframework.lang.Nullable;
import java.util.HashMap;
import java.util.Map;

public enum MineMessageEnum
{
    JJT("jjt", "0001","名称1", Constants.SIFANGJI),
    ZLW("zlw", "0002","名称2",Constants.SIFANGJI),
    CCL("ccl", "0003","名称3",Constants.KEERMA);

    private final String apiCode;
    private final String mineCode;
    private final String mineName;
    private final String signalRule;

    private static final Map<String, MineMessageEnum> mappings = new HashMap<>();

    static
    {
        for (MineMessageEnum messageEnum : values())
        {
            mappings.put(messageEnum.apiCode, messageEnum);
        }
    }

    @Nullable
    public static MineMessageEnum resolve(@Nullable String mineApiCode)
    {
        return (mineApiCode != null ? mappings.get(mineApiCode) : null);
    }

    MineMessageEnum(String apiCode, String mineCode, String mineName,String signalRule)
    {
        this.apiCode = apiCode;
        this.mineCode = mineCode;
        this.mineName = mineName;
        this.signalRule = signalRule;
    }

    public String getApiCode() {
        return apiCode;
    }

    public String getMineCode() {
        return mineCode;
    }

    public String getMineName() {
        return mineName;
    }

    public String getSignalRule() {
        return signalRule;
    }
}

这里使用枚举类来实现,存储apiCode与signalRule的对应关系。

然后再static静态代码块中初始化,将所有的映射关系存储进map,并且提供一个根据key获取value的方法。

6、在实际业务Controller层中

    @GetMapping("/signalright_devs")
    public AjaxResult SignalRightDevs(@RequestParam("mineApiCode") String mineApiCode)
    {
        try{
            MineMessageEnum resolve = MineMessageEnum.resolve(mineApiCode);
            if(null == resolve){
                return AjaxResult.error(HttpStatus.BAD_REQUEST, Constants.NO_API_CODE);
            }else {
                SignalLightRules signalLightRules = signalLightRulesFactory.getSignalLightRules(resolve.getSignalRule());
                List<SignalrightDevsDTO> signalrightDevsDTOS = signalLightRules.getSignalrightDevsDtoList(mineApiCode);
                if(null != signalrightDevsDTOS && signalrightDevsDTOS.size()>0){
                    return AjaxResult.success(signalrightDevsDTOS);
                }else {
                    return AjaxResult.success();
                }
            }
        }catch (Exception exception){
            System.out.println("SignalRightDevs:"+exception.getMessage());
            return AjaxResult.error(HttpStatus.ERROR,Constants.SERVER_ERROR);
        }
    }

首先接口传递apiCode参数,并且判断是否为合法参数,如果不存在则返回自定义错误提示。

存在则获取对应的信号灯规则,通过

signalLightRulesFactory.getSignalLightRules(resolve.getSignalRule());

获取具体规则,注意上面注入信号灯工厂。

    @Autowired
    private SignalLightRulesFactory signalLightRulesFactory;

7、测试

传递规则1对应的apicode,返回对应业务规则数据

 

传递规则2对应的apicode,返回空数据

 

传递非法参数

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot中策略模式+工厂模式业务实例(接口传参-枚举类查询策略映射关系-执行不同策略)规避大量if-else 的相关文章

随机推荐

  • 树09--二叉树的下一个结点

    树09 二叉树的下一个结点 jz57 题目概述 解析 参考答案 注意事项 说明 题目概述 算法说明 给定一个二叉树其中的一个结点 请找出中序遍历顺序的下一个结点并且返回 注意 树中的结点不仅包含左右子结点 同时包含指向父结点的next指针
  • Qt 信号连接多个槽函数 执行顺序

    执行顺序 同一信号连接多个槽呢 槽函数执行没有绝对的先后顺序 如 connect slider QSlider valueChanged spin box QSpinBox setValue connect slider QSlider v
  • 读研期间小论文投稿-个人总结

    我是2014级研究生 学校只是一个普通211 而且工科很弱 导师对我是放养 让我回忆下 上学期就见过她一次 而且她快退休了 没项目没经费没权利 但我觉得跟着她还挺好 因为我可以自己研究自己喜欢的 没人妨碍 但同时导师没有基金 所以我的小论文
  • 两个linux服务器间复制文件

    scp是secure copy的简写 用于在Linux下进行远程拷贝文件的命令 和它类似的命令有cp 不过cp只是在本机进行拷贝不能跨服务器 1 命令格式 scp 参数 原路径 目标路径 2 命令实例 从本地服务器复制到远程服务器 1 复制
  • Vue使用Swiper看这一篇就够了

    Vue使用Swiper看这一篇就够了 此案例实现需求 完成swiper动态异步数据下的slide渲染 自定义分页器样式 解决loop true设置时的事件丢失问题 swiper鼠标移入 移出 暂停 开始轮播 单页面渲染多个swiper组件互
  • 什么是区块链概念

    区块链到底有什么价值 区块链技术被称为价值互联网 大体上原因在于它解决了原有互联网的三个基本问题 第一 区块链通过在数字货币领域的应用 提供了资金流 或者叫资本流 信息在互联网的流动的解决方案 第二 区块链通过加密和分布式账本的引用 解决了
  • 关于Visual Studio 不支持x64 内联汇编分析

    记录一下今天的大坑 实在是有必要记录一下 调程序发现参数在函数传递时 出现了异常的值 已经确认不是指针破坏的问题 用汇编看了下 发现汇编寄存器地址都取错了 在release开启o2优化时出现 关掉又正常 实在是百思不得其解 对于内联汇编 其
  • Mysql根据拼音首字母分组和排序

    最近业务上有个需求 需要根据英文字母展示对应的人名 和我们手机的通讯录差不多 如下图所示 通常如果表设计的时候增加了对应的首字母字段应该很好实现 那如果没加 应该怎么实现呢 图示Sql SELECT name ELT INTERVAL CO
  • Java FileOutputStream类

    文章目录 总结 FileOutputStream类数据结构 FileOutputStream类方法 构造方法 操作方法 总结 FileOutputStream类用于将数据写入文件或文件描述符的输出流 FileOutputStream用于写入
  • 如何查看局域网内所有IP

    要如何查看局域网内正在使用的电脑的IP一共分以下几个步骤 第一步 点击电脑左下角的 开始 然后再点击 运行 第二步 在运行窗口里填入 cmd 然后点击确定 第三步 在cmd命令窗口输入 ipconfig ALL 命令 点击键盘上的回车键 第
  • 2021年字节跳动+京东+美团面试总结!内含福利

    开篇 说一下我大概的情况 渣本毕业 工作已经有快3年了 从高中就开始玩小破站 无论是学习还是日常放松都是在b站 大学主学的软件技术专业 所以 入职bilibili是我大学时期给自己定的小目标 在学校 专业学的算中上的水平 课本知识和老师讲的
  • delphi with do和for do语句

    1 with 对象名 do语句只是为了减少输入的字符 不必每次重复名字 直接写变量 procedure TForm1 Button1Click Sender TObject 正常写法beginedit1 text hello edit1 c
  • J1939协议与CAN2.0对应关系

  • python贪吃蛇小游戏,面向对象设计模式,附带源码以及所需素材

    在python中通过面向对象设计模式来实现一个贪吃蛇小游戏 源码在最下方 上传的资源包内也包括代码源文件以及所需素材等 源文件在game文件夹内 exe文件可直接运行 pygame模块需要自行下载 先来看运行效果图 开始界面 点击按钮开始游
  • Leetcode 括号的分数 -- 栈

    题目描述 leetcode 856 括号的分数 给定一个平衡括号字符串 S 按下述规则计算该字符串的分数 得 1 分 AB 得 A B 分 其中 A 和 B 是平衡括号字符串 A 得 2 A 分 其中 A 是平衡括号字符串 示例 1 输入
  • Go语言学习18-基准测试

    基准测试 引言 基准测试 1 编写基准测试函数 2 计时器 3 内存分配统计 4 基准测试的运行 结语 引言 所谓基准测试 Benchmark Test 简称BMT 是指 通过一些科学的手段实现对一类测试对象的某项性能指标进行可测量 可重复
  • 嵌入式 Linux 入门(七、Linux 下的环境变量)

    嵌入式 Linux 入门第七课 学习理解 linux 的环境变量 矜辰所致 前言 学习完 Linux 的 Shell 命令 和 Shell 脚本 我们还需要理解一个东西 环境变量 理解了 Linux 的环境变量 前面的文章中有些细节的东西
  • OpenCASCADE:使用C#演示的实例

    OpenCASCADE 使用C 演示的实例 OpenCASCADE是一个开源的三维几何建模软件库 它支持多种语言接口 其中 OCCT是OpenCASCADE的C 语言封装 而在本文中 我们将介绍如何使用C 语言来调用OCCT的API 在Vi
  • Mac安装SecureCRT

    踩了很多坑 主要过程 第一次 在之前常用的一个mac软件福利网站https xclient info s securecrt html下载之后发现没有破解文件securecrt mac crack pl 第二次 在csdn上模仿下载之后进行
  • SpringBoot中策略模式+工厂模式业务实例(接口传参-枚举类查询策略映射关系-执行不同策略)规避大量if-else

    场景 设计模式 策略模式在Java中的使用示例 设计模式 策略模式在Java中的使用示例 java 策略模式示例 霸道流氓气质的博客 CSDN博客 上面讲了策略模式在Java中的使用示例 下面看一个在SpringBoot中的实际使用示例 业