当前位置: 首页 > news >正文

使用工厂+策略模式实现去除繁琐的if else

使用工厂+策略模式实现去除繁琐的if else


在中间有一个mapstruct的bug,即在修改实体类中的类型时,或者修改属性名字,mapstruct都无法进行转换,会报错,此时需要maven clean+maven compile即可


前言

在这次的开发中,有一个增加题目的需求,其中题目中有SubjectType对应4种不同的类型,单选多选判断简答。在增加题目的接口中,如果对每个都if一遍,十分繁琐,也不利于后期的扩展,于是选择交给工厂方法去处理,每一个类型的题目有自己的策略类型,然后通过工厂进行创建

创建枚举类型

对应的枚举类型,目的是方便通过传入的Type(值是1234对应四种不同的题型)
并且写出方法根据code找出枚举类

package com.gy.subject.common.enums;public enum SubjectTypeEnum {Radio(1,"单选"),Multiple(2,"多选"),Judge(3,"判断"),Brief(4,"简答");private int code;private String desc;SubjectTypeEnum(int code,String desc){this.code = code;this.desc = desc;}public static SubjectTypeEnum getByCode(int code){for(SubjectTypeEnum x : SubjectTypeEnum.values()){if(x.code == code){return x;}}return null;}
}

创建策略类接口

策略类即却确定了是这个类型,里面包含了具体业务逻辑,比如确定了是单选题之后,那么就要增加一道单选题目,以及后续的业务(此处是把题目对应的标签及分类也增加上)其实后续的业务也可以不在此处添加,让策略类只专注于对于的题型处理

定义了每个具体的策略类可以做获取具体的枚举类,用于后面根据type找出,以及具体的业务增加代码类

package com.gy.subject.domain.handler;import com.gy.subject.common.enums.SubjectTypeEnum;
import com.gy.subject.domain.entity.SubjectInfoBO;
import org.springframework.stereotype.Component;/*** @ClassName SubjectTypeHandeler* @Description 题目处理器* @Author gy* @Date 2024/12/29*/
@Component
public interface SubjectTypeHandeler {/*** @Description: 获取处理器类型* @Param: []* @return: com.gy.subject.common.enums.SubjectTypeEnum* @Author: gy* @Date: 2024/12/29*/SubjectTypeEnum getHandelerType();/*** @Description: 添加题目* @Param: [subjectInfoBO]* @return: void* @Author: gy* @Date: 2024/12/29*/void add(SubjectInfoBO subjectInfoBO);}

具体的策略类

以创建一个单选为例,实现抽象策略类接口

package com.gy.subject.domain.handler;import com.google.common.base.Preconditions;
import com.gy.subject.common.enums.SubjectTypeEnum;
import com.gy.subject.domain.convert.RadioSubjectConverter;
import com.gy.subject.domain.entity.SubjectInfoBO;
import com.gy.subject.infra.basic.entity.SubjectMapping;
import com.gy.subject.infra.basic.entity.SubjectRadio;
import com.gy.subject.infra.basic.service.SubjectMappingService;
import com.gy.subject.infra.basic.service.SubjectRadioService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;/*** @ClassName RadioTypeHandler* @Description 单选的处理器* @Author gy* @Date 2024/12/29*/
@Component
public class RadioTypeHandler implements SubjectTypeHandeler {@Resourceprivate SubjectRadioService subjectRadioService;@Resourceprivate SubjectMappingService subjectMappingService;/*** @Description: 获取单选处理器类型* @Param: []* @return: com.gy.subject.common.enums.SubjectTypeEnum* @Author: gy* @Date: 2024/12/29*/@Overridepublic SubjectTypeEnum getHandelerType() {return SubjectTypeEnum.Radio;}/*** @Description: 添加题目* @Param: [subjectInfoBO]* @return: void* @Author: gy* @Date: 2024/12/29*/@Overridepublic void add(SubjectInfoBO subjectInfoBO) {List<SubjectRadio> radioList = new LinkedList<>();//List<SubjectMapping> subjectMappingList = new LinkedList<>();Preconditions.checkNotNull(radioList,"单选的四个答案list不能为空");subjectInfoBO.getOptionList().forEach(option -> {SubjectRadio radio = RadioSubjectConverter.INSTANCE.converterAnswerToRadio(option);radio.setSubjectId(subjectInfoBO.getId());radioList.add(radio);});subjectRadioService.batchInsert(radioList);//        subjectInfoBO.getCategoryIds().forEach(categoryId -> {
//            subjectInfoBO.getLabelIds().forEach(labelId -> {
//                SubjectMapping subjectMapping = new SubjectMapping();
//                subjectMapping.setSubjectId(subjectInfoBO.getId());
//                subjectMapping.setCategoryId(Long.valueOf(categoryId));
//                subjectMapping.setLabelId(Long.valueOf(labelId));
//                subjectMappingList.add(subjectMapping);
//            });
//        });
//
//        subjectMappingService.batchInsert(subjectMappingList);}
}

接下来可以创建不同的题型,如若想要扩展题型,那么只需要增加一个枚举类

创建工厂类

工厂类中从bean工厂中找出题型的策略类组成一个list,目的是注入到map中,方便根据type从map中直接找出具体策略类。

其实不用map也可以,直接遍历一次,通过enum的value.code 进行对比,使用map技术层面来说更好

package com.gy.subject.domain.handler;import com.gy.subject.common.enums.SubjectTypeEnum;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/**** 题目类型工厂* @author 高悦* @version 1.0* @description: TODO* @date 2024/12/29 17:09*/@Component
public class SubjectTypeHandlerFactory implements InitializingBean {@Resourceprivate List<SubjectTypeHandeler> subjectTypeHandelerList;private Map<SubjectTypeEnum,SubjectTypeHandeler> subjectTypeHandelerMap = new HashMap<>();public SubjectTypeHandeler getSubjectTypeHandler(int SubjectType){SubjectTypeEnum subjectTypeEnum = SubjectTypeEnum.getByCode(SubjectType);return subjectTypeHandelerMap.get(subjectTypeEnum);}@Overridepublic void afterPropertiesSet() throws Exception {for(SubjectTypeHandeler x : subjectTypeHandelerList){subjectTypeHandelerMap.put(x.getHandelerType(),x);}}
}

业务层

业务层中就可以解放了,工厂直接根据type选择到具体的策略然后执行业务

//上一个工厂加策略的形式//一个工厂 包含了4种类型,根据传入的type自动映射选择处理//可以节省一大堆的if(因为题目信息里面要有选择是单选还是多选)SubjectInfo subjectInfo = SubjectInfoBOConverter.INSTANCE.SubjectInfoBOtoInfo(subjectInfoBO);SubjectInfo insert = subjectInfoService.insert(subjectInfo);subjectInfoBO.setId(insert.getId());SubjectTypeHandeler subjectTypeHandler = subjectTypeHandlerFactory.getSubjectTypeHandler(subjectInfoBO.getSubjectType());subjectTypeHandler.add(subjectInfoBO);

相关文章:

使用工厂+策略模式实现去除繁琐的if else

使用工厂策略模式实现去除繁琐的if else 在中间有一个mapstruct的bug&#xff0c;即在修改实体类中的类型时&#xff0c;或者修改属性名字&#xff0c;mapstruct都无法进行转换&#xff0c;会报错&#xff0c;此时需要maven cleanmaven compile即可 前言 在这次的开发中&#…...

Dubbo3入门项目搭建

开发环境&#xff1a;jdk8、dubbo3.2.9、nacos2.3.0、springboot2.7.17、dubbo-admin0.6.0。 Dubbo 是一个高性能的 Java RPC&#xff08;远程调用&#xff09;框架&#xff0c;最初由阿里巴巴开发并开源&#xff0c;主要用于构建 SOA 架构下的分布式应用系统( soa简单理解就是…...

形象地理解UE4中的数据结构 TLinkedListBase

大家都熟知链表&#xff0c;但不一定能快速看懂UE4中的数据结构。 TLinkedListBase表示“链接”中的一个结点&#xff0c;有三个成员&#xff1a; 一、ElementType Element; 表示具体的业务&#xff0c;例如int链条中的一个整数。 二、NextLink 表示 “下一个Node”&#…...

Python自然语言处理利器:SnowNLP模块深度解析、安装指南与实战案例

Python自然语言处理之SnowNLP模块介绍、安装与常见操作案例 一、SnowNLP模块介绍 SnowNLP是一个专为中文文本设计的Python库&#xff0c;它基于自然语言处理技术&#xff0c;提供了多种功能&#xff0c;包括分词、词性标注、情感分析、文本转换&#xff08;简繁转换&#xff…...

Llama系列关键知识总结

系列文章目录 第一章&#xff1a;LoRA微调系列笔记 第二章&#xff1a;Llama系列关键知识总结 第三章&#xff1a;LLaVA模型讲解与总结 文章目录 系列文章目录Llama: Open and Efficient Foundation Language Models关键要点LLaMa模型架构&#xff1a;Llama2分组查询注意力 (G…...

【开源】创建自动签到系统—QD框架

1. 介绍 QD是一个 基于 HAR 编辑器和 Tornado 服务端的 HTTP 定时任务自动执行 Web 框架。 主要通过抓包获取到HAR来制作任务模板&#xff0c;从而实现异步响应和发起HTTP请求 2. 需要环境 2.1 硬件需求 CPU&#xff1a;至少1核 内存&#xff1a;推荐 ≥ 1G 硬盘&#xff1a;推…...

​​​​​​​CDP集群安全指南系列文章导读

[一]大数据安全综述 1-认证 身份验证是任何计算环境的基本安全要求。简单来说&#xff0c;用户和服务必须在使用系统功能并获得授权之前&#xff0c;向系统证明其身份&#xff08;进行身份验证&#xff09;。身份验证与授权紧密配合&#xff0c;共同保护系统资源。大多数 CDH …...

MT8788安卓核心板_MTK8788核心板参数_联发科模块定制开发

MT8788安卓核心板是一款尺寸为52.5mm x 38.5mm x 2.95mm的高集成度电路板&#xff0c;专为各种智能设备应用而设计。该板卡整合了处理器、图形处理单元(GPU)、LPDDR3内存、eMMC存储及电源管理模块&#xff0c;具备出色的性能与低功耗特性。 这款核心板搭载了联发科的MT8788处理…...

【微软,模型规模】模型参数规模泄露:理解大型语言模型的参数量级

模型参数规模泄露&#xff1a;理解大型语言模型的参数量级 关键词&#xff1a; #大型语言模型 Large Language Model #参数规模 Parameter Scale #GPT-4o #GPT-4o-mini #Claude 3.5 Sonnet 具体实例与推演 近日&#xff0c;微软在一篇医学相关论文中意外泄露了OpenAI及Claud…...

深入理解并发原子性、可见性、有序性与JMM内存模型

1. 并发三大特性 并发编程Bug的源头&#xff1a;原子性、可见性和有序性问题 1.1 原子性 一个或多个操作&#xff0c;要么全部执行且在执行过程中不被任何因素打断&#xff0c;要么全部不执行。在 Java 中&#xff0c;对基本数据类型的变量的读取和赋值操作是原子性操作&…...

电商项目-数据同步解决方案(四)商品下架同步更新ES索引库数据

商品下架索引库删除数据 一、 需求分析和业务逻辑 商品下架后将商品从索引库中移除。 主要应用技术有&#xff1a; 消息队列-RabbitMQ &#xff0c;分布式搜索引擎-ElasticSearch&#xff0c;Eureka&#xff0c;Canal&#xff0c;Feign远程调用 &#xff08;1&#xff09;在…...

vue学习第一阶段

vue 什么是Vue? 概念:Vue是一个构建用户页面的渐进式框架 Vue的两种使用方式 Vue的核心开发 场景: 局部 {\color{red}局部} 局部模块改造Vue核心包& Vue插件 工程化开发场景: 整站 {\color{red}整站} 整站开发Vue2官网 https://v2.cn.vuejs.org/ 资料存放地址 D:\Baidu…...

React虚拟DOM:理解和应用

写在前面 在现代前端开发中&#xff0c;React 是一个非常流行的 JavaScript 库&#xff0c;用于构建用户界面。它引入了一个名为“虚拟 DOM”&#xff08;Virtual DOM&#xff09;的概念&#xff0c;这个概念对于 React 的高效性能和易用性至关重要。本文将深入探讨 React Vir…...

用python编写一个放烟花的小程序

import pygame import random # 代码解释及使用说明&#xff1a; # 首先&#xff0c;导入 pygame 和 random 库。pygame 用于创建游戏窗口和图形绘制&#xff0c;random 用于生成随机数。 # 初始化 pygame&#xff0c;并设置屏幕尺寸为 800x600 像素&#xff0c;设置窗口标题为…...

Git 仓库与文件管理笔记

Git 的三种仓库概念 本地仓库 (Local Repository) 位于本地 .git 文件夹中通过 git init 或 git clone 创建存储完整的项目历史和分支信息 远程仓库 (Remote Repository) 位于 GitHub、GitLab 等平台服务器使用 git remote -v 查看所有远程仓库默认远程仓库名通常为 origin 工…...

2024 年 docker 提示index.docker.io

发现 docker 提示以下错误&#xff1a; Error response from daemon: Get "https://index.docker.io/v1/search?qnginx&n25": dialing index.docker.io:443 container via direct connection because has no HTTPS proxy: connecting to index.docker.io:443:…...

TCP粘/拆包----自定义消息协议

今天是2024年12月31日&#xff0c;今年的最后一天&#xff0c;希望所有的努力在新的一年会有回报。❀ 无路可退&#xff0c;放弃很难&#xff0c;坚持很酷 TCP传输 是一种面向二进制的&#xff0c;流的传输。在传输过程中最大的问题是消息之间的边界不明确。而在服务端主要的…...

Modbus知识详解

Modbus知识详解 ## 1.什么是Modbus?**顾名思义**&#xff0c;它是一个Bus&#xff08;总线&#xff09;&#xff0c;即总线协议。比如串口协议、IIC协议、SPI都是通信协议。你接触到这种协议&#xff0c;相信你所处的行业是工业电子方面或者你的产品用于工业。好了&#xff0c…...

Java-创建一个结合CompletableFuture和自定义功能的工具类

1.重试机制:当异步任务失败时自动重试。 2.超时重试:在指定时间内未完成的任务进行重试。 3.批量处理:将多个任务批量执行并收集结果。 4.日志记录:为每个异步任务添加日志记录,便于调试和监控。 5.自定义线程池:允许用户传入自定义的线程池配置。 import java.util…...

【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算

【MATLAB第111期】基于MATLAB的sobol全局敏感性分析方法二阶指数计算 一、简介 在MATLAB中计算Sobol二阶效应指数通常涉及到全局敏感性分析&#xff08;Global Sensitivity Analysis, GSA&#xff09;&#xff0c;其中Sobol方法是一种流行的技术&#xff0c;用于评估模型输入…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...