if-else深度优化:巧用状态变更枚举

Posted amberjava

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了if-else深度优化:巧用状态变更枚举相关的知识,希望对你有一定的参考价值。

If-else 过多,代码不易读,后人也不敢轻易修改。

个人觉得有如下几种优化方式,网上不胜枚举,可以自行百度,但是小编说的这个方法《if-else深度优化:巧用状态变更枚举》,网上例子不多。

 

技术图片

 

 

 

业务场景:
例如在无人仓业务场景中,货架都放在储位上(储位就是地面上标记的某个点),正向流程:货架状态需要从空闲->预占->占用中->预释放->空闲。逆向流程相反。
储位状态需要根据不同的业务场景变更。

正常情况下,A服务请求批量变更储位状态,需要先校验状态是否正确,能否变更,if-else方法。在更新数据库构造更新体时,还需要设置变更前状态,变更后状态,if-else方法。

未优化前:

1.更新前校验

根据不同状态,判断是否可以变更。不能变更,返回错误体。

其中多重if-else嵌套,返回的错误信息也是+拼接

 1  for (StorageLocation requestPoint : request.getPointList()) {
 2             int taskType = requestPoint.getStorageStatus();
 3             if (PositionTaskType.PREOCCUPY.getTaskType().equals(taskType)) { //预占操作
 4                 if (!StorageStatusEnum.INIT.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
 5                     logger.error("{} 校验{}储位状态异常, 预占操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.INIT.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
 6                     response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 预占操作,状态应该是" + StorageStatusEnum.INIT.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
 7                     return response;
 8                 }
 9 
10             }else if (PositionTaskType.RELEASEPREOCCUPY.getTaskType().equals(taskType)) { //撤销预占操作
11                 if (!StorageStatusEnum.PREOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
12                     logger.error("{} 校验{}储位状态异常, 撤销预占操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PREOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
13                     response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 撤销预占操作,状态应该是" + StorageStatusEnum.PREOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
14                     return response;
15                 }
16 
17             }else if (PositionTaskType.OCCUPY.getTaskType().equals(taskType)) { //占用操作
18                 if (!StorageStatusEnum.PREOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
19                     logger.error("{} 校验{}储位状态异常, 占用操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PREOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
20                     response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 占用操作,状态应该是" + StorageStatusEnum.PREOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
21                     return response;
22                 }
23 
24             }else if (PositionTaskType.PRERELEASE.getTaskType().equals(taskType)) { //预释放操作
25                 if (!StorageStatusEnum.OCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
26                     logger.error("{} 校验{}储位状态异常, 预释放操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.OCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
27                     response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 预释放操作,状态应该是" + StorageStatusEnum.OCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
28                     return response;
29                 }
30 
31             }else if (PositionTaskType.REVOKPRERELEASE.getTaskType().equals(taskType)) { //撤销预释放操作
32                 if (!StorageStatusEnum.PRERELEASEOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
33                     logger.error("{} 校验{}储位状态异常, 预释放操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PRERELEASEOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
34                     response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 撤销预释放操作,状态应该是" + StorageStatusEnum.PRERELEASEOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
35                     return response;
36                 }
37 
38             }else if (PositionTaskType.RELEASE.getTaskType().equals(taskType)) { //预释放操作
39                 if (!StorageStatusEnum.PRERELEASEOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
40                     logger.error("{} 校验{}储位状态异常, 预释放操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PRERELEASEOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
41                     response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 预释放操作,状态应该是" + StorageStatusEnum.PRERELEASEOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
42                     return response;
43                 }
44             }
45         }

 

2.构造更新体代码。同样问题,if-else过多

 1 private QueryPoint getUpdatePoint( BatchPreReleaseStorageLocationRequest request,String operatorName,StorageLocation requestPoint){
 2         QueryPoint updatePoint = new QueryPoint();
 3         //条件
 4         updatePoint.setAreaId(request.getMapAreaId());
 5         updatePoint.setOrgNo(request.getOrgNo());
 6         updatePoint.setDistributeNo(request.getDistributeNo());
 7         updatePoint.setWarehouseNo(request.getWarehouseNo());
 8         updatePoint.setPositionId(requestPoint.getPoint());
 9         updatePoint.setUpdateUser(operatorName);
10         updatePoint.setContainerNo(requestPoint.getContainerNo());
11 
12         if (PositionTaskType.PREOCCUPY.getTaskType().equals(requestPoint.getStorageStatus())) { //预占操作
13             updatePoint.setStorageStatus(StorageStatusEnum.PREOCCUPY.getStatus());
14             updatePoint.setOldStorageStatus(StorageStatusEnum.INIT.getStatus());
15         }else if (PositionTaskType.RELEASEPREOCCUPY.getTaskType().equals(requestPoint.getStorageStatus())) { //撤销预占操作
16             updatePoint.setStorageStatus(StorageStatusEnum.INIT.getStatus());
17             updatePoint.setOldStorageStatus(StorageStatusEnum.PREOCCUPY.getStatus());
18         }else if (PositionTaskType.OCCUPY.getTaskType().equals(requestPoint.getStorageStatus())) { //占用操作
19             updatePoint.setStorageStatus(StorageStatusEnum.OCCUPY.getStatus());
20             updatePoint.setOldStorageStatus(StorageStatusEnum.PREOCCUPY.getStatus());
21         }else if (PositionTaskType.PRERELEASE.getTaskType().equals(requestPoint.getStorageStatus())) { //预释放操作
22             updatePoint.setStorageStatus(StorageStatusEnum.PRERELEASEOCCUPY.getStatus());
23             updatePoint.setOldStorageStatus(StorageStatusEnum.OCCUPY.getStatus());
24         }else if (PositionTaskType.REVOKPRERELEASE.getTaskType().equals(requestPoint.getStorageStatus())) { //撤销预释放操作
25             updatePoint.setStorageStatus(StorageStatusEnum.OCCUPY.getStatus());
26             updatePoint.setOldStorageStatus(StorageStatusEnum.PRERELEASEOCCUPY.getStatus());
27         }else if (PositionTaskType.RELEASE.getTaskType().equals(requestPoint.getStorageStatus())) { //预释放操作
28             updatePoint.setStorageStatus(StorageStatusEnum.INIT.getStatus());
29             updatePoint.setContainerNo("");
30             updatePoint.setOldStorageStatus(StorageStatusEnum.PRERELEASEOCCUPY.getStatus());
31         }
32         return updatePoint;
33     }

 

 

 

优化后:

1.新增一个状态变更枚举类

public enum PositionTaskTypeStatus {
    PREOCCUPY(1, "预占用",0,1),
    RELEASEPREOCCUPY(2, "释放预占用",1,0),
    OCCUPY(3, "占用",1,10),
    PRERELEASE(4, "预释放",10,3),
    REVOKPRERELEASE(5, "撤销预释放",3,10),
    RELEASE(6, "释放",3,0),

    ;

    private Integer taskType;
    private String taskName;
    private Integer fromStatus;
    private Integer toStatus;


    private static Map<Integer, PositionTaskTypeStatus> map = new HashMap<>();
    static {
        for (PositionTaskTypeStatus task : PositionTaskTypeStatus.values()) {
            map.put(task.getTaskType(), task);
        }
    }

    PositionTaskTypeStatus(Integer taskType, String taskName, Integer fromStatus, Integer toStatus) {
        this.taskType = taskType;
        this.taskName = taskName;
        this.fromStatus = fromStatus;
        this.toStatus = toStatus;
    }

    public Integer getTaskType() {
        return taskType;
    }

    public void setTaskType(Integer taskType) {
        this.taskType = taskType;
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }

    public Integer getFromStatus() {
        return fromStatus;
    }

    public void setFromStatus(Integer fromStatus) {
        this.fromStatus = fromStatus;
    }

    public Integer getToStatus() {
        return toStatus;
    }

    public void setToStatus(Integer toStatus) {
        this.toStatus = toStatus;
    }

    public static Map<Integer, PositionTaskTypeStatus> getMap() {
        return map;
    }

    public static void setMap(Map<Integer, PositionTaskTypeStatus> map) {
        PositionTaskTypeStatus.map = map;
    }

    public static String getTaskNameByTaskType(Integer taskType) {
        String taskName = "";
        for (PositionTaskTypeStatus e : PositionTaskTypeStatus.values()) {
            if (e.taskType.equals(taskType)) {
                taskName = e.taskName;
            }
        }
        return taskName;
    }

    public static boolean contains(Integer taskType){
        if(null == taskType){
            return false;
        }
       return map.containsKey(taskType)?true:false;
    }

    public static PositionTaskTypeStatus getEnumByKey(Integer taskType){
        return map.get(taskType);
    }

    /**
     * 操作类型、原始值是否可以修改
     * @param taskType
     * @param originalValue
     * @return
     */
    public static boolean verify(Integer taskType,Integer originalValue){
        if(null==getEnumByKey(taskType)){
            return false;
        }
        if(!getEnumByKey(taskType).getFromStatus().equals(originalValue)){
            return false;
        }
        return true;
    }

 

2.更新前校验代码片段。

枚举状态变更类+google的前置检查方法,一行搞定。

//校验状态是否在枚举之内
        for(StorageLocation requestPoint : request.getPointList()){
            Preconditions.checkArgument(PositionTaskTypeStatus.contains(requestPoint.getStorageStatus()),"%s操作类型%s不存在",requestPoint.getPoint(),requestPoint.getStorageStatus());
        }

3.构造更新体代码

 1 private QueryPoint getUpdatePoint( BatchPreReleaseStorageLocationRequest request,StorageLocation requestPoint){
 2         QueryPoint updatePoint = new QueryPoint();
 3         updatePoint.setAreaId(request.getMapAreaId());
 4         updatePoint.setOrgNo(request.getOrgNo());
 5         updatePoint.setDistributeNo(request.getDistributeNo());
 6         updatePoint.setWarehouseNo(request.getWarehouseNo());
 7         updatePoint.setPositionId(requestPoint.getPoint());
 8         updatePoint.setUpdateUser(request.getOperatorName());
 9         updatePoint.setContainerNo(requestPoint.getContainerNo());
10         updatePoint.setStorageStatus(PositionTaskTypeStatus.getEnumByKey(requestPoint.getStorageStatus()).getToStatus()); //枚举类,设置更新状态
11         updatePoint.setOldStorageStatus(PositionTaskTypeStatus.getEnumByKey(requestPoint.getStorageStatus()).getFromStatus()); //枚举类 设置原始状态
12         return updatePoint;
13     }

 

看过后有没有恍然大悟的感觉,看看您代码中是否有这样的场景,赶快优化吧~~

笔者之后遇到的项目,都按照这种思想编码。有的项目业务状态多大20多种,if-else会看的很头疼。

 

以上是关于if-else深度优化:巧用状态变更枚举的主要内容,如果未能解决你的问题,请参考以下文章

Stateless状态机的简单应用

Stateless状态机的简单应用

巧用Python 枚举类设计状态码信息

巧用Python 枚举类设计状态码信息

巧用Python 枚举类设计状态码信息

语法糖甜不甜?巧用枚举实现“状态”转换限制