问题场景
在使用枚举类时,每个枚举值都能代表一类业务,且每类业务在多个接口都有不同的处理逻辑,这样我们使用枚举驱动策略,防止出现太多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);
}
}
为每条流程添加自己的处理类,当再新加流程时只需要加一个新的处理类就可以了。
