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

使用工厂+策略模式实现去除繁琐的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 {

    @Resource
    private SubjectRadioService subjectRadioService;

    @Resource
    private SubjectMappingService subjectMappingService;

    /**
    * @Description: 获取单选处理器类型
    * @Param: []
    * @return: com.gy.subject.common.enums.SubjectTypeEnum
    * @Author: gy
    * @Date: 2024/12/29
    */

    @Override
    public SubjectTypeEnum getHandelerType() {
        return SubjectTypeEnum.Radio;
    }

    /**
    * @Description: 添加题目
    * @Param: [subjectInfoBO]
    * @return: void
    * @Author: gy
    * @Date: 2024/12/29
    */

    @Override
    public 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 {
    @Resource
    private List<SubjectTypeHandeler> subjectTypeHandelerList;

    private Map<SubjectTypeEnum,SubjectTypeHandeler> subjectTypeHandelerMap = new HashMap<>();

    public SubjectTypeHandeler getSubjectTypeHandler(int SubjectType){
        SubjectTypeEnum subjectTypeEnum = SubjectTypeEnum.getByCode(SubjectType);
        return subjectTypeHandelerMap.get(subjectTypeEnum);
    }

    @Override
    public 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);

http://www.kler.cn/a/459455.html

相关文章:

  • 论文泛读《LPFHE: Low-Complexity Polynomial CNNs for Secure Inference over FHE》
  • 我的桌面 1.9.75 | 个性化定制手机桌面,丰富的小组件和主题
  • 交换机关于环路、接口绑定、链路聚合的相关知识
  • xilinx的高速接口构成原理和连接结构及ibert工具的使用-以k7 GTX为例
  • 网络安全 | 信息安全管理体系(ISMS)认证与实施
  • ESP32-S3遇见OpenAI:OpenAI官方发布ESP32嵌入式实时RTC SDK
  • 菲尼克斯超级工厂落地南京,汽车市场被瞄准
  • FreeRTOS的时间管理
  • CSS过渡(transition)
  • 【Rust自学】8.2. Vector + Enum的应用
  • 第1关:博客系统数据库设计与实现之查询
  • bacnet mstp设备数据 转 opc ua项目案例
  • vue实现平滑滚动到目标标签页
  • 数据结构-1-线性表
  • Azure DevOps Server:使用TfsDeleteProject.exe删除团队项目
  • 第四期书生大模型实战营 第10关 InternVL 多模态模型部署微调实践
  • WebRTC :原理、协议和应用场景
  • 24.12.27 SpringMVCDay02
  • python3中条件判断语句:if 语句与if嵌套语句
  • CSS利用浮动实现文字环绕右下角,展开/收起效果
  • 从论文到实践:Stable Diffusion模型一键生成高质量AI绘画
  • 【笔记️】魔爪 Mini mx 使用快捷键
  • 深入解析C#异步编程:await 关键字背后的实现原理
  • Vue.js 生命周期概述:组件从诞生到销毁的全过程
  • Python世界:函数模块知识点小结
  • pytorch torch.utils.checkpoint模块介绍