if-else深度优化:巧用状态变更枚举(代码片段)

amberjava amberjava     2022-12-14     358

关键词:

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会看的很头疼。

 

语法糖甜不甜?巧用枚举实现“状态”转换限制(代码片段)

语法糖语法糖(Syntacticsugar),也被译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(PeterJ.Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,... 查看详情

开发中巧用enum枚举类型——转自翘首以望(代码片段)

在实际开发中,在数据库表设计中,我们往往习惯于用一个Int类型的State字段去表示数据的状态,这个字段很方便去表示这条数据的状态,但是又不愿意去建一张这个State字段的外键表去解释状态。(这一类型表状态的字段可能... 查看详情

if-else代码优化的八种方案(代码片段)

前言代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。优化方案一:提前return,去除不必要的else如果if-else代码块包含return语句,可以考虑通过提... 查看详情

巧用python枚举类设计状态码信息(代码片段)

引言在web项目中,我们经常使用自定义状态码来告知请求方请求结果以及请求状态;在Python中该如何设计自定义的状态码信息呢?普通类加字典设计状态码#!/usr/bin/python3#-*-coding:utf-8-*-#@Author:Hui#@Desc:项目响应码... 查看详情

java中巧用枚举减少代码量(代码片段)

 先看原来的代码:List<Integer>activityValue=MallUtil.stringToArrayInt(this.activity);activityValue.forEach(e->ProductTypeEnumtypeEnum=ProductTypeEnum.getByValue(e);activity.add(Object 查看详情

优化if-else代码的八种方案(代码片段)

前言代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。优化方案一:提前return,去除不必要的else如果if-else代码块包含return语句,可以考虑通过提... 查看详情

优化if-else代码的八种方案!(代码片段)

前言代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。优化方案一:提前return,去除不必要的else如果if-else代码块包含return语句,可以考虑通过提... 查看详情

优化if-else的想法(代码片段)

在日常代码中,总是不能避开if-else,虽然它很好,可是需要至少三行代码,真的很丑,而且业务代码里,动辄十几个if-else,实在不方便代码阅读。所以我有一个不成熟的想法,在有限的业务范围内,用Dictionary<K,V>代替。首先... 查看详情

if-else代码优化,优雅点好不(代码片段)

代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。优化方案一:提前return,去除不必要的else如果if-else代码块包含return语句,可以考虑通过提前retur... 查看详情

stateless状态机的简单应用

...据不同操作,来变更到各种相应的值,最基础的做法就是if-else,好处在于简单;坏处在于代码冗长不便于维护,比如参数要精准控制从什么状态变到什么状态的话最坏情况需要写一遍所有状态的if-else,然后每个动作都要判断一... 查看详情

可以一学的代码优化小技巧:减少if-else冗余(代码片段)

摘要:if-else语句对于程序员来说,是非常非常熟悉的一个判断语句,我们在日常开发和学习中都经常看见它。本文分享自华为云社区《JavaScript代码之美—代码优化,减少if-else冗余的技巧》,作者:黛琳ghz... 查看详情

可以一学的代码优化小技巧:减少if-else冗余(代码片段)

摘要:if-else语句对于程序员来说,是非常非常熟悉的一个判断语句,我们在日常开发和学习中都经常看见它。本文分享自华为云社区《JavaScript代码之美—代码优化,减少if-else冗余的技巧》,作者:黛琳ghz... 查看详情

代码中大量的if-else,你有什么优化方案?(代码片段)

...度,我们往往忽略代码的可读性与扩展性,不合理的使用if-else条件判断会使我们的程序复杂度大大提升,同时也会使代码的可读性急速下降,后期维护难度也大大提高,真的让人脑壳疼。比如下方示例://贷款申请操作的处理fun... 查看详情

javase选择结构——优化if-else的嵌套代码(代码片段)

1.业务场景在业务场景中,经常会出现很复杂的ifelse嵌套,譬如下面这种情况:👇👇👇//请按你的实际需求修改参数publicStringconvertCountryName(StringfullName)if("china".equalsIgnoreCase(fullName))return 查看详情

源码深度解读:vuex的一些缺陷(收藏!)(代码片段)

众所周知,Vuex是Flux架构的一种实现。Flux清晰确立了数据管理场景下各种职能单位,其主要准则有:中心化状态管理状态只能通过专门 突变 单元进行变更应用层通过发送信号(一般称action),触发变更Vuex也是紧紧... 查看详情

巧用location.hash保存页面状态(代码片段)

在我们的项目中,有大量ajax查询表单+结果列表的页面,由于查询结果是ajax返回的,当用户点击列表的某一项进入详情页之后,再点击浏览器回退按钮返回ajax查询页面,这时大家都知道查询页面的表单和结... 查看详情

php邮寄状态变更邮件(代码片段)

查看详情

巧用import.meta实现热更新(代码片段)

import.metaimport.meta是一个给JavaScript模块暴露特定上下文的元数据属性的对象,它包含了这个模块的信息。import.meta对象是由ECMAScript实现的,它带有一个null的原型对象。这个对象可以扩展,并且它的属性都是可写,... 查看详情