枚举策略驱动

问题场景

在使用枚举类时,每个枚举值都能代表一类业务,且每类业务在多个接口都有不同的处理逻辑,这样我们使用枚举驱动策略,防止出现太多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);
    }

}

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

相关推荐
小杨互联网24 分钟前
项目CyberScan Pro jar软件安全成分分析插件
java·jar·软件成分分析·jar安全分析
组合缺一37 分钟前
Java 版 Claude Code CLI 来了!(国产开源项目)Solon Code CLI 发布
java·ai·开源·llm·solon·cli·claudecode
javaIsGood_2 小时前
Java基础面试题
java·开发语言
indexsunny2 小时前
互联网大厂Java求职面试实战:基于电商场景的技术问答及解析
java·spring boot·redis·kafka·security·microservices·面试指导
Forget_85502 小时前
RHEL——LVS模式
java·开发语言·lvs
渣瓦攻城狮2 小时前
互联网大厂Java面试:从数据库连接池到分布式缓存及微服务
java·redis·spring cloud·微服务·hikaricp·数据库连接池·分布式缓存
罗超驿3 小时前
13.1 万字长文,深入解析--抽象类和接口
java·开发语言
A懿轩A3 小时前
【Java 基础编程】Java 面向对象进阶:static/final、抽象类、接口、单例模式
java·开发语言·单例模式
lifallen3 小时前
后缀数组 (Suffix Array)
java·数据结构·算法
逆境不可逃3 小时前
LeetCode 热题 100 之 76.最小覆盖子串
java·算法·leetcode·职场和发展·滑动窗口