【问题标题】:Cyclomatic Complexity reduction圈复杂度降低
【发布时间】:2016-02-26 23:43:48
【问题描述】:

我有一段代码在降低其圈复杂度时遇到问题。由于必须匹配多个条件,我不确定进一步分解它的最佳方法。使事情复杂化的是,在其中两种情况下创建了一个新对象,但在第三种情况下没有创建(它调用另一个方法)。这是伪代码:

    if (!cond3 && !cond1 && cond2 && cond4) {
        // actions to perform
        calculateValues();
        return result;
    } else if (!cond1 && cond2 && cond3) {
        // actions to perform
        Object result = new Result();
        return result;
    } else if (!cond4 && cond3 && cond1 && cond5) {
        // actions to perform
        Object result = new Result();
        return result;
    } else {
        // throw error because inputs are invalid
    }

【问题讨论】:

  • 问题是 Sonar 说 CC 是 12,我们的阈值是 10。我觉得它也很好,但我们必须遵守这个阈值。

标签: java cyclomatic-complexity


【解决方案1】:

您应该重构该代码,使用方法来抽象这些条件,高圈表示代码需要重构。例如,假设:!cond4 && cond3 && cond1 && cond5 测试登录的用户是否有车,那么您应该将该条件组合重构为一个方法:

private boolean loggedUserHasCar() {
    return !cond4 && cond3 && cond1 && cond5;
}

对其他条件做同样的事情。 if 具有 4 个条件的语句很难阅读。提取这些语句将降低您的方法圈复杂度并使您的代码更具可读性

【讨论】:

    【解决方案2】:

    我对您的问题非常感兴趣,并尝试了早期提出的解决方案,其中提取条件以分离这样的方法

    public class Test {
    
    public static void main(String[] args) {
        cyclometricComplexityTest();
    }
    
    static boolean cond1 = true;
    static boolean cond2 = true;
    static boolean cond3 = true;
    static boolean cond4 = true;
    static boolean cond5 = true;
    
    public static Object cyclometricComplexityTest() {
        if (isBoolean1()) {
            // actions to perform
            Object result = null;
            calculateValues();
            return result;
        } else if (isBoolean2()) {
            // actions to perform
            Object result = new Result();
            return result;
        } else if (isBoolean3()) {
            // actions to perform
            Object result = new Result();
            return result;
        } else {
            throw new RuntimeException();
        }
    }
    
    static boolean isBoolean1() {
        return !cond3 && !cond1 && cond2 && cond4;
    }
    
    private static boolean isBoolean2() {
        return !cond1 && cond2 && cond3;
    }
    
    private static boolean isBoolean3() {
        return !cond4 && cond3 && cond1 && cond5;
    }
    
    static void calculateValues() {}
    
    static class Result {}
    }
    

    减少 Cyclometric Complexity 的结果在这里(我使用了MetricsReloaded IntelliJ IDEA plugin)。它确实通过分散主要和辅助方法之间的复杂性来起作用:)

    附:有趣的事情:我试图将您的条件提取为局部变量,但它并没有像我最初预期的那样降低方法的复杂性。

    【讨论】:

      【解决方案3】:

      您可以将方程的公共部分提取为新变量,从而将循环复杂度降低到 11

      boolean common = !cond1 && cond2;
      ...
      if (!cond3 && common && cond4) {
          // actions to perform
          calculateValues();
          return result;
      } else if (common && cond3) {
          // actions to perform
          Object result = new Result();
          return result;
      } else if (!cond4 && cond3 && cond1 && cond5) {
          // actions to perform
          Object result = new Result();
          return result;
      } else {
          // throw error because inputs are invalid
      }     
      

      【讨论】:

        猜你喜欢
        • 2020-10-03
        • 1970-01-01
        • 1970-01-01
        • 2020-06-13
        • 1970-01-01
        相关资源
        最近更新 更多