声纳圈复杂度规则问题 - 不鼓励多个返回语句

时间:2014-05-22 09:33:24

标签: java sonarqube cyclomatic-complexity

对于下面的代码,sonarqube计算方法圈复杂度为9

String foo() {
    if (cond1) return a;
    if (cond2) return b;
    if (cond3) return c;
    if (cond4) return d;
    return e;
}

我理解根据计算规则http://docs.sonarqube.org/display/SONAR/Metrics+-+Complexity,9的复杂性是正确的。 因此该方法的复杂性是= 4(如果)+ 4(返回)+ 1(方法)= 9

如果我有一个退出点,这种复杂性可以降低。

String foo() {
    String temp;
    if (cond1) { 
        temp = a;
    } else if (cond2) {
        temp = b;
    } else if (cond3) { 
        temp = c;
    } else if (cond4) {
        temp = d;
    } else {
        temp = e;
    }
    return temp;
}

我相信这段代码比以前的版本更混乱,更难以理解,我觉得拥有返回保护条件的方法是一种更好的编程习惯。那么有什么理由可以考虑返回语句来计算圈复杂度?可以改变计算逻辑,使其不会促进单一退出点。

4 个答案:

答案 0 :(得分:9)

我同意你应该使用一些常识并使用你认为最简单的代码。

BTW如果您使用? :

,您可以简化代码并只返回一次
String foo() {
    return cond1 ? a :
           cond2 ? b :
           cond3 ? c :
           cond4 ? d : e;
}

答案 1 :(得分:2)

其他答案对所涉及的计算有所了解。

我想指出你断言代码不太可读是错误的,因为在一个例子中你有大括号,而在另一个例子中你没有。

String foo() {
  String output = e;
  if (cond1) output = a;
  else if (cond2) output = b;
  else if (cond3) output = c;
  else if (cond4) output = d;

  return output;
}

这与您使用return语句提供的示例一样可读。 是否允许使用无括号if语句是一个风格问题,您可能应该在所有代码中保持一致。

圈复杂度 解决的更重要的问题是,如果计算cond1,cond2等的值有副作用,即如果它们是有状态方法而不是这种情况下的字段,那么如果你可以提前返回,那么代码的概念复杂性要高得多,如果不能的话。

答案 2 :(得分:1)

  

“因此有充分理由考虑返回陈述   计算圈复杂度?计算逻辑可以吗?   改变,以便它不会促进单一退出点。“

在你的例子中,多次返回并不会增加复杂性,因为@Peter Lawrey说你应该运用常识。

这是否意味着多个return语句的所有示例复杂性并且应该删除它?我不这么认为。如果很容易想出一个由于多个return语句而难以阅读的方法的例子。想象一下100行方法,其中包含4个不同的返回语句。这就是这条规则试图捕捉的问题。

答案 3 :(得分:0)

这是一个已知的圈复杂度问题。

还有充分的理由认为圈复杂度是无用的。它与SLOC强烈相关,而与实际错误无关。事实上,SLOC与圈复杂度一样,也是缺陷的预测指标。大多数其他复杂度指标也是如此。

请参阅http://www.leshatton.org/Documents/TAIC2008-29-08-2008.pdf,从幻灯片16开始。