如何优化代码中大量的if/else, switch/case ?

  

前言

  

随着项目的迭代,代码中存在的分支判断可能会越来越多,当里面涉及到的逻辑比较复杂或者分支数量实在是多的难以维护的时候,我们就要考虑下,有办法能让这些代码变得更优雅吗?

  

正文

  
使用枚举h5> 这里我们简单的定义一个表示状态的枚举。

  
 <代码类="语言java ">公共枚举状态{
  新(0),可运行(1),(2),(3)阻塞,死(4);
  
  公共int statusCode;
  
  状态(int statusCode) {
  这一点。statusCode=statusCode;
  }
  } 
  

那么我们在使用的时候就可以直接通过枚举调用了。

  
 <代码类="语言java "> int statusCode=Status.valueOf(“新”).statusCode;  
  

优雅的解决了下面代码赋值的方式

  
 <代码类="语言java ">如果(param.equals(“新”)){
  statusCode=0;
  }else if (param.equals (RUNNABLE)) {
  statusCode=1;
  }
  … 
  
善用可选
  

在项目中,总少不了一些非空的判断,可能大部分人还是如下的用法

  
 <代码类="语言java ">如果(null==用户){//action1
  其他}{//action2
  } 
  

这时候该掏出可选这个秘密武器了,它可以让非空校验更加优雅,间接的减少如果操作。没了解过可选的同学可自行谷歌,这里就不再赘述。

  
 <代码类="语言java "> OptionaluserOptional=Optional.ofNullable(用户);
  userOptional.map (action1) .orElse (action2);  
  

上面的代码跟第一段是等效的,通过一些新特性让代码更加紧凑。

  
表驱动法
  

来自谷歌的解释:表驱动法是一种编程模式,它的本质是,从表里查询信息来代替逻辑语句(如果)。下面看一个案例,通过月份来获取当月的天数(仅作为案例演示,获取2月份的数据不严谨),普通做法:

  
 <代码类="语言java "> int getMonthDays (int) {
  开关(月){
  案例1:返回31;断裂;
  案例2:返回29;断裂;
  案例3:返回31;断裂;
  案例4:返回30;断裂;
  案例5:返回31;断裂;
  案例6:返回30;断裂;
  案例7:返回31;断裂;
  例8:返回31;断裂;
  案例9:返回30;断裂;
  例10:返回31;断裂;
  例11:返回30;断裂;
  例12:返回31;断裂;
  默认值:返回0;
  }
  } 
  

表驱动法实现方式

  
 <代码类="语言java "> int monthday[12]={31日31日31日,29日,30日,30日,31日,31日,30日,31日,30日,31};
  int getMonthDays (int) {
  返回monthday[——月];
  } 
  

其实这里的表就是数组而已,通过直接查询数组来获得需要的数据,那么同理,地图之类的容器也可以成为我们编程概念中的表。

  
 <代码类="语言java "> Map<?Function<比;action>,actionsMap=new HashMap<的在();//初试配置对应动作
  actionsMap。把(value1, (someParams)→{doAction1 (someParams)});
  actionsMap。把(value2, (someParams)→{doAction2 (someParams)});
  actionsMap。put (value3 (someParams)→{doAction3 (someParams)});//省略空判断
  actionsMap.get(参数)苹果(someParams);  
  

通过Java8的λ表达式,我们把需要执行东西存进价值中,调用的时候通过匹配钥匙的方式进行。

  
提前判断返回
  

在之前的文章《优化代码中的“坏味道”》里也有提过,如下语句

  
 <代码类="语言java ">
  如果(条件){//难道
  其他}{
  返回;
  } 
  

改为   

 <代码类="语言java ">如果(!条件){
  返回;
  }//难道 
  

避免一些不必要的分支,让代码更精炼。

  
其他方法
  

除了上面提到的方法,我们还可以通过一些设计模式,例如策略模式,责任链模式等来优化存在大量,如果这样的情况,其原理会和表驱动的模式比较相似,大家可以自己动手实现一下,例如我们在网状的的使用过程中,可能会出现需要大量判断不同的命令去执行对应动作的场景。

  
 <=坝镅詊ava代码类> ServerHandler.java
  
  如果(command.equals(“登录”)){//执行登录
  }else if (command.equals(“聊天”)){//聊天
  }else if (command.equals(“广播”)){//广播信息
  }
  ....  
  

该如何处理呢?这里先卖个关子,大家可以先思考一下,笔记后续会写一些关于网状的实现我的文章,到时候会详细介绍。

  

结语

  

最后要明确一点,不是所有的if/else, switch/case都需要优化,当我们发现有“痛”点或者“闻到代码有坏味道“再来优化才是最好的,不然你可能会写了一个从不扩展的可扩展代码,所有的优化都是为了更好的迭代项目,更好的服务于业务,而不是为了优化而优化。

如何优化代码中大量的if/else, switch/case ?