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

news2025/1/16 1:56:04

场景

设计模式-策略模式在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,返回空数据

 

传递非法参数

 

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

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

相关文章

推荐一些非常好用的DNS服务器

推荐一些非常好用的DNS服务器 1、114公共DNS服务器 1&#xff09; 老牌的114DNS&#xff0c;全国三网通用高速&#xff0c;纯净无劫持无需再忍受被强扭去看广告或粗俗网站之痛苦 DNS地址为&#xff1a;114.114.114.114 和 114.114.115.115 2&#xff09;拦截 钓鱼病毒木马网…

三顾茅庐,七面阿里,终拿25k*16offer,我的面试历程

写在片头&#xff1a;声明&#xff0c;勿杠 首先简单说一下&#xff0c;这三次面试阿里并不是一次性去面的&#xff0c;实际上第一次面试时候还在大四&#xff0c;找的实习岗&#xff0c;不太清楚是什么部门&#xff0c;别问我为什么还记得面试题&#xff0c;有记录和复盘的习…

DX算法还原

早在之前作者就写过一篇关于顶象的滑块验证&#xff0c;潦潦草草几句话就带过了。 出于互相学习的想法&#xff0c;给了一个大学生&#xff0c;奈何不讲武德把源码甩群里了&#xff0c;虽然在大佬们眼里不难&#xff0c; 不过拿着别人的东西乱传还是不太好。自认倒霉&#xf…

基于max30102的物联网病房监测系统(传感驱动和数据处理)

目录 一、实物展示 二、主体介绍 三、MAX30102的驱动 四、MAX30102的数据处理 奋斗一个星期&#xff0c;每个引脚都是扒皮焊接然后再把皮包回去的。这几天吸的垃圾气体感觉要少活两年。 一、实物展示 这次吸取上次教训&#xff0c;把线捆起来好多了 二、主体介绍 用的传感…

Python进阶篇

大家好&#xff0c;我是易安&#xff01;今天我们继续Python的学习&#xff0c;内容稍微有些多&#xff0c;不过我会尽可能举一些例子让你理解。 对象比较与拷贝 在前面的学习中&#xff0c;我们其实已经接触到了很多 Python对象比较和复制的例子&#xff0c;比如下面这个&…

【JVM】面试题总结

JVM 1、JVM 的运行时内存区域是怎样的2、堆和栈的区别3、Java 中的对象一定在堆上分配内存吗4、什么是 Stop The World5、JVM 如何判断对象是否存活6、JVM 有哪些垃圾回收算法7、什么是三色标记算法8、新生代和老年代的GC算法9、新生代和老年代的垃圾回收器有何区别10、Java 中…

【SVN】版本控制管理的文件(夹)如何重命名

目录 一、前言二、操作步骤1. 使用SVN重命名&#xff08;SVN rename&#xff09;2. 输入新名称3. 确定重命名4. 立刻进行一次提交&#xff08;commit&#xff09;5. 补充 三、可能遇到的问题1. 情况一2. 情况二3. 情况三 一、前言 如果只是在本地的文件系统中修改SVN中的文件&a…

迈巴赫GLS480升级行政四座,享受霸气豪华老板座

头等舱级后排独立座椅可奉上私人飞机般的旅程体验。无论是美观性还是功能性&#xff0c;商务型中央控制台都可为后排乘客带来巨大优势。例如&#xff0c;在电动开启盖板下方贴心地为乘客提供控温杯座以及储物箱。您可在扶手下方为您的智能手机进行无线感应充电。

亚马逊云科技开启您的云财务管理之旅:云财务运营

亚马逊云科技“开启您的云财务管理之旅”系列内容提出了关于如何启动和实施一个成功的云财务管理CFM战略的建议。云财务管理CFM的三个原则&#xff1a;SEE-查看、SAVE-节省和PLAN-计划。接下来介绍的是第四个阶段&#xff1a;RUN-运营。 在这一阶段&#xff0c;可以了解云财务管…

JavaScript全解析——canvas 绘制图片

●在 canvas 内也是可以直接插入一个图片的 ●如果在 canvas 内想插入一个图片 ○首先要用 js 加载一个图片 ○当图片加载完毕以后, 我们在用 canvas 的 API 把它插入到画布上即可 ●先用 js 加载一张图片出来 const myImg new Image() myImg.sec ./01小锋.png // 准备一个加…

数据结构与算法基础(王卓)(33):折半插入排序、希尔排序

目录 折半插入排序 Project 1: 问题&#xff1a;缺少在插入元素之前的移动元素的操作 Project 2:&#xff08;最终成品、结果&#xff09; 希尔排序 Project 1:&#xff08;个人思路&#xff09; 标准答案&#xff1a;&#xff08;PPT答案&#xff09; 解释说明&#xff…

OpenGL(六)——坐标系统

目录 一、前言 二、空间系 2.1 局部空间 2.2 世界空间 2.3 观察空间 2.4裁剪空间 2.5 正射投影 2.6 透视投影 2.7 屏幕空间 三、透视箱子 3.1 创建模型矩阵 3.2 创建观察矩阵 3.3 创建透视投影矩阵 3.4 修改顶点着色器 3.5 传递变换矩阵 四、旋转的箱子 五、好…

面了一圈,还没拿到offer.....

最近收到很多小伙伴的留言&#xff0c;金三银四过完了一个offer都没收到。还有遇到那种特别喜欢怼人的面试官&#xff0c;直接面到怀疑人生&#xff0c;真是让人费解。。。 其实面试受打击是正常的&#xff0c;关键是要在面试中总结自己的不足&#xff01;提前做好面试准备和技…

java基于知识库的中医药问询系统

本系统主要包含了等系统用户管理、中医药常识管理、科室信息管理、知识库管理多个功能模块。下面分别简单阐述一下这几个功能模块需求。 管理员的登录模块&#xff1a;管理员登录系统对本系统其他管理模块进行管理。 用户的登录模块&#xff1a;用户登录本系统&#xff0c;对个…

简历投了2个月没有面试,看这趋势,不发力是不行了

最近有朋友吐槽&#xff0c;感觉最近好难&#xff0c;简历投了2个月了&#xff0c;面试机会很少&#xff0c;自己每天也费心费力的投&#xff0c;一有新职位就赶紧投&#xff0c;自己也积极的跟人家打招呼&#xff0c;不是看完那边没有回复&#xff0c;要么就是不合适。于是我就…

基于ARM树莓派实现智能家居:语音识别控制,Socket网络控制,火灾报警检测,实时监控

目录 一 项目说明 ① 设计框架 ② 功能说明 ③ 硬件说明 ④ 软件说明 二 项目代码 <1> mainPro.c 主函数 <2> InputCommand.h 控制设备头文件 <3> contrlDevices.h 外接设备头文件 <4> bathroomLight.c 泳池灯 <5> livin…

【GUI】基于Python的文本数据处理(串口解析 0D 0A结尾)

【GUI】基于Python的文本数据处理&#xff08;串口解析 0D 0A结尾&#xff09; 如有串口数据&#xff1a; [37;22mD/NO_TAG [2023-04-24 23:01:06 ] ------------------------------------------------->>>>>> M_DADAT_GET_DAMAGE_INFO [0m 2023/04/24 2…

200左右什么蓝牙耳机比较好?国产200左右蓝牙耳机推荐

随着不少手机厂商取消3.5mm耳机孔&#xff0c;蓝牙耳机便成为了人们外出的最佳选择。最近看到很多人问&#xff0c;200左右什么蓝牙耳机比较好&#xff1f;针对这个问题&#xff0c;我来给大家推荐几款国产的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡小音舱Lite2蓝牙耳机 …

如何防止订单重复支付

想必大家对在线支付都不陌生&#xff0c;今天和大家聊聊如何防止订单重复支付。 看看订单支付流程 我们来看看&#xff0c;电商订单支付的简要流程&#xff1a; 订单钱包支付流程 从下单/计算开始&#xff1a; 下单/结算&#xff1a;这一步虽然不是直接的支付起点&#xff0c;但…

opencv场景识别

opencv场景识别 文章目录 一、需求1、现状2、设想 二、模型使用1、opencv dnn支持的功能2、ANN_MLP相关知识3、MLP图像分类模型训练学习 三、更换方向1、目标检测模型2、darknet网络介绍 四、opencv调用darknet模型1、**darknet模型获取**2、python调用darknet模型3、遇到的一些…