服务器安装网站,用redis加速wordpress,正规营销型网站建设公司,马蹄室内设计官网使用工厂策略模式实现去除繁琐的if else 在中间有一个mapstruct的bug#xff0c;即在修改实体类中的类型时#xff0c;或者修改属性名字#xff0c;mapstruct都无法进行转换#xff0c;会报错#xff0c;此时需要maven cleanmaven compile即可 前言
在这次的开发中#…使用工厂策略模式实现去除繁琐的if else 在中间有一个mapstruct的bug即在修改实体类中的类型时或者修改属性名字mapstruct都无法进行转换会报错此时需要maven cleanmaven 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) {ListSubjectRadio radioList new LinkedList();//ListSubjectMapping 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 ListSubjectTypeHandeler subjectTypeHandelerList;private MapSubjectTypeEnum,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);