Code Smell : If-Statements : 条件语句

问题概述

if可能是代码中最常用的逻辑控制语句,但不合理的复杂的if会让代码变得冗长复杂难以理解.

if让代码的逻辑分支成指数级上升.不合理的if还会带来深层嵌套问题.

症状

  • 过多的if语句
  • if语句缺少else
  • 相同或类似的条件出现在多个if语句中
  • 多个if语句块中存在退出语句(抛异常,返回值),而且散落在代码各处
  • 多个if语句块中抛出了相同的异常内容.

可能的解决方案

  • 翻转逻辑.人们更容易理解正向逻辑,所以尽可能在if语句中使用正向条件判断.如果一定要使用逆向逻辑条件,请将该条件封装为一个方法并提供便于理解的方法名.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //逆向条件
    if(! exists(something)){
    doSomeThingA();
    }else{
    doSomeThingB();
    }

    //重构为正向,上面的代码在Intellij IDEA中会有高亮提示
    //按下Alt+Enter可以在弹出的菜单中选择"invert 'if' condition",即可自动重构为下面的代码
    if(exists(something)){
    doSomeThingB();
    }else{
    doSomeThingA();
    }
  • 如果前面的代码中已经对某个条件进行了判断(例如判断某个变量是否为null),那么后续代码中出现的相同判断都可以移除.

  • 代码中通过一系列的if(without else)来控制流程,那么要思考一下是否可以通过通过添加else来简化流程.一系列的if表达所有的代码都可能会被执行,而if-else表达的是二选一来执行.if-else不仅简化了代码,令逻辑更容易理解,而且还提升了代码的执行效率.

  • 一旦你减少了代码中对相同条件的重复判断,就可以将这些if语句块提取到具有良好明明的自解释的方法中.这可以极大的改善代码的可读性.

  • 一些简单的校验或检查会导致提前退出或返回的代码,请放到方法的最顶端.这样代码读者可以清楚知道哪些代码不是主要逻辑可以跳过.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if(args[length] >= 1){
    // some lang code;
    doSomethingWith(args[0]);
    }else{
    return -1;
    }

    //上述代码可以改为
    if(args[length] < 1){
    return -1
    }
    // some lang code;
    doSomeThingWith(args[0]);
  • 将异常语句放在最后的else语句中,这样读者可以明确知道,这是在所有条件判断都失败的情况下做出的处理.