zoukankan      html  css  js  c++  java
  • 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会看的很头疼。

    持续优化:

    参考: 用Java8 Lambda重构简单工厂模式   https://segmentfault.com/a/1190000021803985ttps://segmentfault.com/a/1190000021641277

    ==========================================================================           如果您觉得这篇文章对你有帮助,可以【关注我】或者【点赞】,希望我们一起在架构的路上,并肩齐行
    ==========================================================================
  • 相关阅读:
    JUC-狂神笔记整理学习
    多线程-学习笔记
    Redis分布锁
    Redis
    springcloud一个简单的基本流程
    Nacos
    mysql单表查询
    mysql多表查询
    mysql数据库
    mysql详细安装教程以及1067错误代码解决方案
  • 原文地址:https://www.cnblogs.com/amberJava/p/12974976.html
Copyright © 2011-2022 走看看