枚举策略驱动

问题场景

在使用枚举类时,每个枚举值都能代表一类业务,且每类业务在多个接口都有不同的处理逻辑,这样我们使用枚举驱动策略,防止出现太多if判断的场景。

我的使用场景:我有多条OA流程,每个枚举值代表一个流程,在多个接口中都需要对不同的流程进行不同的处理,原先是使用多个if判断处理,当流程越来越多到if判断越来越多,使得代码可读性变差,不容易扩展,所以使用枚举驱动策略,也更符合面向对象的思想。

问题场景举例:

java 复制代码
@Override
public List<DeptSimpleRespVO> getSimpleMentDeptList(String proKey) {
    DeptDO deptDO = deptMapper.selectById(getLoginUserDeptId());
    List<DeptDO> list = new ArrayList<>();
    if("1".equals(deptDO.getDeptType())){
        DeptListReqVO reqVO = new DeptListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
        if(BpmProcessKeyEnum.LB_PROCESS_KEY_A.getValue().equals(proKey)){
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setWarZone(deptDO.getWarZone());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.LB_PROCESS_KEY_B.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.LB_PROCESS_KEY_C.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.LB_PROCESS_KEY_D.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setWarZone(deptDO.getWarZone());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.LB_PROCESS_KEY_E.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_PROCESS_KEY_A.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setWarZone(deptDO.getWarZone());
            reqVO.setUnitNature(DeptNatureEnum.ZYCK.getType());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_PROCESS_KEY_B.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setUnitNature(DeptNatureEnum.ZYCK.getType());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_PROCESS_KEY_C.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setUnitNature(DeptNatureEnum.ZYCK.getType());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_PROCESS_KEY_D.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setUnitNature(DeptNatureEnum.DSCK.getType());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_DJ_A.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setWarZone(deptDO.getWarZone());
            reqVO.setUnitNature(DeptNatureEnum.DSCK.getType());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_DJ_B.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setUnitNature(DeptNatureEnum.DSCK.getType());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_DJ_C.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setWarZone(deptDO.getWarZone());
            reqVO.setUnitNature(DeptNatureEnum.DSCK.getType());
            list = deptMapper.selectbtList(reqVO);
        } else if (BpmProcessKeyEnum.HJ_DJ_D.getValue().equals(proKey)) {
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            reqVO.setUnitNature(DeptNatureEnum.DSCK.getType());
            list = deptMapper.selectbtList(reqVO);
        }
    }
    List<DeptDO> nodeAndAllChildren = new ArrayList<>();
    FlatNodeUtil.findAllChildren(list, deptDO.getMentToDeptId(), nodeAndAllChildren);
    nodeAndAllChildren = nodeAndAllChildren.stream().filter(e -> e.getIsBzd() != 4).collect(Collectors.toList());
    return BeanUtils.toBean(nodeAndAllChildren, DeptSimpleRespVO.class);
}

使用注解驱动策略后:

java 复制代码
@Override
public List<DeptSimpleRespVO> getSimpleMentDeptList(String proKey) {
    DeptDO deptDO = deptMapper.selectById(getLoginUserDeptId());
    List<DeptDO> list = new ArrayList<>();
    if("1".equals(deptDO.getDeptType())){
        DeptListReqVO reqVO = new DeptListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus());
        // 一行代码取代所有if判断
        ProStrategyContext.executeChuCunDianWei(reqVO, deptDO, proKey);
        list = deptMapper.selectbtList(reqVO);
    }
    List<DeptDO> nodeAndAllChildren = new ArrayList<>();
    FlatNodeUtil.findAllChildren(list, deptDO.getMentToDeptId(), nodeAndAllChildren);
    nodeAndAllChildren = nodeAndAllChildren.stream().filter(e -> e.getIsBzd() != 4).collect(Collectors.toList());
    return BeanUtils.toBean(nodeAndAllChildren, DeptSimpleRespVO.class);
}

具体实现

普通流程枚举类

java 复制代码
/**
 * 流程枚举
 *
 * @author 马朋帅
 */
@Getter
@AllArgsConstructor
public enum BpmProcessKeyEnum {

    // A
    LB_PROCESS_KEY_A("A颜色内部库容统筹调配", "oamy001", true),
    LB_PROCESS_KEY_B("A内部跨颜色库容统筹调配", "oamy002", true),
    LB_PROCESS_KEY_C("A内部库容统筹调配", "oamy003", true),

    // B
    HJ_PROCESS_KEY_A("B颜色内战役仓库库容统筹调配", "oahj001", true),
    HJ_PROCESS_KEY_B("B内跨颜色战役仓库库容统筹调配", "oahj002", true),
    HJ_PROCESS_KEY_C("B内战役仓库库容统筹调配", "oahj003", true),
    HJ_PROCESS_KEY_D("B内跨颜色队属仓库库容统筹调配", "oahj004", true),
    HJ_DJ_A("B颜色内队属仓库库容统筹调配", "djhj001", false),
    HJ_DJ_B("B内队属仓库库容统筹调配", "djhj002", false),
    HJ_DJ_C("B颜色内战时库容统筹调配", "djhj003", false),
    HJ_DJ_D("B内战时库容统筹调配", "djhj004", false),
    HJ_DJ_E("B部队内队属仓库库容统筹调配", "djhj005", false),
    HJ_PROCESS_KEY_E("B部队内战役仓库库容统筹调配", "oahj005", true),
    HJ_PROCESS_KEY_F("B颜色内跨部队战役仓库库容统筹调配", "oahj006", true),
    HJ_PROCESS_KEY_G("B内跨部队战役仓库库容统筹调配", "oahj007", true),
    HJ_PROCESS_KEY_L("B颜色内跨部队队属仓库库容统筹调配", "oahj008", true),
    HJ_PROCESS_KEY_I("B内跨部队队属仓库库容统筹调配", "oahj009", true),

    // 跨型号
    LB_PROCESS_KEY_D("颜色内部跨型号库容统筹调配", "oamy004", true),
    LB_PROCESS_KEY_E("跨颜色跨型号库容统筹调配", "oamy005", true);


    /**
     * 流程名称
     */
    private final String label;
    /**
     * 流程key
     */
    private final String value;
    /**
     * 是否走流程
     */
    private final Boolean sflc;

    public static BpmProcessKeyEnum getLiuCheng(String value) {
        return ArrayUtil.firstMatch(item -> item.getValue().equals(value), BpmProcessKeyEnum.values());
    }

}

处理器枚举类:实现枚举类跟处理器类的绑定。

java 复制代码
/**
 * 流程枚举
 *
 * @author 马朋帅
 */
@Getter
@AllArgsConstructor
public enum BpmProcessKeyStrategyEnum {

    // A
    LB_A(BpmProcessKeyEnum.LB_PROCESS_KEY_A, new LbProcessKeyAStrategy()),
    LB_B(BpmProcessKeyEnum.LB_PROCESS_KEY_B, new LbProcessKeyBStrategy()),
    LB_C(BpmProcessKeyEnum.LB_PROCESS_KEY_C, new LbProcessKeyCStrategy()),

    // B
    HJ_A(BpmProcessKeyEnum.HJ_PROCESS_KEY_A, new HjProcessKeyAStrategy()),
    HJ_B(BpmProcessKeyEnum.HJ_PROCESS_KEY_B, new HjProcessKeyBStrategy()),
    HJ_C(BpmProcessKeyEnum.HJ_PROCESS_KEY_C, new HjProcessKeyCStrategy()),
    HJ_D(BpmProcessKeyEnum.HJ_PROCESS_KEY_D, new HjProcessKeyDStrategy()),
    HJ_E(BpmProcessKeyEnum.HJ_PROCESS_KEY_E, new HjProcessKeyEStrategy()),
    HJ_F(BpmProcessKeyEnum.HJ_PROCESS_KEY_F, new HjProcessKeyFStrategy()),
    HJ_G(BpmProcessKeyEnum.HJ_PROCESS_KEY_G, new HjProcessKeyGStrategy()),
    HJ_L(BpmProcessKeyEnum.HJ_PROCESS_KEY_L, new HjProcessKeyLStrategy()),
    HJ_I(BpmProcessKeyEnum.HJ_PROCESS_KEY_I, new HjProcessKeyIStrategy()),
    HJ_DJ_N_A(BpmProcessKeyEnum.HJ_DJ_A, new HjProcessKeyNAStrategy()),
    HJ_DJ_N_B(BpmProcessKeyEnum.HJ_DJ_B, new HjProcessKeyNBStrategy()),
    HJ_DJ_N_C(BpmProcessKeyEnum.HJ_DJ_C, new HjProcessKeyNCStrategy()),
    HJ_DJ_N_D(BpmProcessKeyEnum.HJ_DJ_D, new HjProcessKeyNDStrategy()),
    HJ_DJ_N_E(BpmProcessKeyEnum.HJ_DJ_E, new HjProcessKeyNEStrategy()),

    // 跨型号
    LB_D(BpmProcessKeyEnum.LB_PROCESS_KEY_D, new LbProcessKeyDStrategy()),
    LB_E(BpmProcessKeyEnum.LB_PROCESS_KEY_E, new LbProcessKeyEStrategy());

    /**
     * 流程枚举
     */
    private final BpmProcessKeyEnum bpmProcessKeyEnum;
    /**
     * 流程处理器
     */
    private final ProStrategy proStrategy;

    public static BpmProcessKeyStrategyEnum getChuLiQiMeiJu(String value) {
        return ArrayUtil.firstMatch(item -> item.getBpmProcessKeyEnum().getValue().equals(value), BpmProcessKeyStrategyEnum.values());
    }

}

处理器类的上层接口

java 复制代码
/**
 * 流程策略接口
 */
public interface ProStrategy {

    /**
     * 储存点位策略
     * @param reqVO
     * @param deptDO
     */
    void chuCunDianWei(DeptListReqVO reqVO, DeptDO deptDO);

    /**
     * 处理辅助决策策略
     * @param pageReqVO
     * @param deptDO
     */
    void fuZhuJueChe(SystemFzjcPageReqVO pageReqVO, DeptDO deptDO);

    /**
     * 获取流程初始流程变量策略
     * @return
     */
    Map<String, Object> getChuShiLiuChengBianLiang();

    /**
     * 获取流程节点的部门和部门用户策略
     * @param kxyh
     * @return
     */
    List<DeptBmSimpleRespVO> getJieDianBuMenHeYongHu(String kxyh, DeptMapper deptMapper, PostMapper postMapper, AdminUserMapper userMapper);

}

具体处理类

java 复制代码
public class HjProcessKeyAStrategy implements ProStrategy {

    @Override
    public void chuCunDianWei(DeptListReqVO reqVO, DeptDO deptDO) {
        reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
        reqVO.setWarZone(deptDO.getWarZone());
        reqVO.setUnitNature(DeptNatureEnum.ZYCK.getType());
    }

    @Override
    public void fuZhuJueChe(SystemFzjcPageReqVO pageReqVO, DeptDO deptDO) {
        pageReqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
        pageReqVO.setWarZone(deptDO.getWarZone());
        pageReqVO.setUnitNature(DeptNatureEnum.ZYCK.getType());
    }

    @Override
    public Map<String, Object> getChuShiLiuChengBianLiang() {
        Map<String, Object> processInstanceVariables = new HashMap<>();
        return processInstanceVariables;
    }

    @Override
    public List<DeptBmSimpleRespVO> getJieDianBuMenHeYongHu(String kxyh, DeptMapper deptMapper, PostMapper postMapper, AdminUserMapper userMapper) {
        return getNodeDeptUser(getNodeDept(kxyh, deptMapper), postMapper, userMapper, kxyh);
    }

    /**
     * 获取每个节点的对应部门
     * @param kxyh
     * @return
     */
    public List<DeptBmSimpleRespVO> getNodeDept(String kxyh, DeptMapper deptMapper){
        DeptListReqVO reqVO = new DeptListReqVO();
        reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
        List<DeptDO> list = new ArrayList<>();
        if("oahj00101".equals(kxyh)){
            DeptDO deptDO = deptMapper.selectById(getLoginUserDeptId());
            // 设置查询条件
            reqVO.setBmType(DeptBmlxEnum.ZQJHC.getType());
            reqVO.setIsBzd(5);
            reqVO.setWarZone(deptDO.getWarZone());
            reqVO.setSubordinateMilitaryBranches(deptDO.getSubordinateMilitaryBranches());
            list = deptMapper.selectBmList(reqVO);
        }
        return BeanUtils.toBean(list, DeptBmSimpleRespVO.class);
    }

    /**
     * 获取每个节点的对应部门用户
     * @param listVo
     * @return
     */
    public List<DeptBmSimpleRespVO> getNodeDeptUser(List<DeptBmSimpleRespVO> listVo, PostMapper postMapper, AdminUserMapper userMapper, String kxyh){
        // 查询岗位信息
        List<PostDO> gwList = postMapper.selectList();
        Map<Long, PostDO> longPostDOMap = CollectionUtils.convertMap(gwList, PostDO::getId);
        // 查询全部用户信息
        List<UserSimpleRespVO> userList = BeanUtils.toBean(userMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus()), UserSimpleRespVO.class);
        for (DeptBmSimpleRespVO dept : listVo) {
            for (UserSimpleRespVO user : userList) {
                if(dept.getId().equals(user.getDeptId())){
                    // 设置部门信息
                    user.setBmType(dept.getBmType());
                    user.setDeptName(dept.getName());
                    user.setDeptType(dept.getDeptType());
                    List<UserSimpleRespVO> userList1 = dept.getUserList();
                    // 排除分管领导
                    Set<Long> postIds = user.getPostIds();
                    boolean fgldyh = false;
                    for (Long postId : postIds) {
                        PostDO postDO = longPostDOMap.get(postId);
                        // 分管领导用户
                        if(PostDO.FGLD_CODE.equals(postDO.getCode())){
                            fgldyh = true;
                        }
                    }
                    // 添加普通领导用户
                    if (!fgldyh) {
                        if(CollectionUtil.isEmpty(userList1)){
                            userList1 = new ArrayList<>();
                            userList1.add(user);
                        }else {
                            userList1.add(user);
                        }
                    }
                    dept.setUserList(userList1);
                }
            }
            // 设置是否多选按钮
            dept.setShowAddBtn(false);
        }
        return listVo;
    }

}

策略类:不同接口只需要调用它就行,它会找到具体的处理类进行处理。

java 复制代码
public class ProStrategyContext {

    /**
     * 处理存储点位接口
     * @param reqVO
     * @param deptDO
     * @param proKey
     */
    public static void executeChuCunDianWei(DeptListReqVO reqVO, DeptDO deptDO, String proKey){
        if(null == reqVO || null == deptDO || StringUtils.isBlank(proKey)){
            throw new ServiceException(500, "executeChuCunDianWei参数为空");
        }
        BpmProcessKeyStrategyEnum chuLiQiMeiJu = BpmProcessKeyStrategyEnum.getChuLiQiMeiJu(proKey);
        if(null == chuLiQiMeiJu || null == chuLiQiMeiJu.getProStrategy()){
            throw new ServiceException(500, proKey + "处理器枚举为空");
        }
        chuLiQiMeiJu.getProStrategy().chuCunDianWei(reqVO, deptDO);
    }

    /**
     * 处理辅助决策接口
     * @param pageReqVO
     * @param deptDO
     * @param proKey
     */
    public static void executeFuZhuJueChe(SystemFzjcPageReqVO pageReqVO, DeptDO deptDO, String proKey){
        if(null == pageReqVO || null == deptDO || StringUtils.isBlank(proKey)){
            throw new ServiceException(500, "executeFuZhuJueChe参数为空");
        }
        BpmProcessKeyStrategyEnum chuLiQiMeiJu = BpmProcessKeyStrategyEnum.getChuLiQiMeiJu(proKey);
        if(null == chuLiQiMeiJu || null == chuLiQiMeiJu.getProStrategy()){
            throw new ServiceException(500, proKey + "处理器枚举为空");
        }
        chuLiQiMeiJu.getProStrategy().fuZhuJueChe(pageReqVO, deptDO);
    }

    /**
     * 获取流程初始流程变量
     * @param proKey
     * @return
     */
    public static Map<String, Object> getChuShiLiuChengBianLiang(String proKey){
        if(StringUtils.isBlank(proKey)){
            throw new ServiceException(500, "getChuShiLiuChengBianLiang参数为空");
        }
        BpmProcessKeyStrategyEnum chuLiQiMeiJu = BpmProcessKeyStrategyEnum.getChuLiQiMeiJu(proKey);
        if(null == chuLiQiMeiJu || null == chuLiQiMeiJu.getProStrategy()){
            throw new ServiceException(500, proKey + "处理器枚举为空");
        }
        return chuLiQiMeiJu.getProStrategy().getChuShiLiuChengBianLiang();
    }

    /**
     * 获取流程节点的部门和部门用户
     * @param kxyh
     * @param proKey
     * @return
     */
    public static List<DeptBmSimpleRespVO> getJieDianBuMenHeYongHu(String kxyh, String proKey, DeptMapper deptMapper, PostMapper postMapper, AdminUserMapper userMapper){
        if(StringUtils.isBlank(kxyh) || StringUtils.isBlank(proKey)){
            throw new ServiceException(500, "getJieDianBuMenHeYongHu参数为空");
        }
        BpmProcessKeyStrategyEnum chuLiQiMeiJu = BpmProcessKeyStrategyEnum.getChuLiQiMeiJu(proKey);
        if(null == chuLiQiMeiJu || null == chuLiQiMeiJu.getProStrategy()){
            throw new ServiceException(500, proKey + "处理器枚举为空");
        }
        return chuLiQiMeiJu.getProStrategy().getJieDianBuMenHeYongHu(kxyh, deptMapper, postMapper, userMapper);
    }

}

为每条流程添加自己的处理类,当再新加流程时只需要加一个新的处理类就可以了。

相关推荐
马猴烧酒.2 小时前
【JAVA数据传输】Java 数据传输与转换详解笔记
java·数据库·笔记·tomcat·mybatis
爱编码的傅同学2 小时前
【常见锁的概念】死锁的产生与避免
java·开发语言
rabbit_pro3 小时前
SpringBoot3使用PostGis+GeoTools整合MybatisPlus
java·spring
望眼欲穿的程序猿3 小时前
Ai8051U+DHT11温湿度!
java·开发语言
一只大马猴呀3 小时前
IntelliJ IDEA 中启动项目不显示端口号
java·ide·intellij-idea
Hx_Ma164 小时前
Map集合的5种遍历方式
java·前端·javascript
小手cool4 小时前
Java 列表中查找最小值和最大值最有效率的方法
java
惊讶的猫4 小时前
多线程同步问题及解决
java·开发语言·jvm
wfsm4 小时前
工厂模式创建动态代理实现类
java·开发语言