3

我将 SonarQube 用于 Java 项目,但复杂度计算对我来说并不清楚。以下示例的复杂度值为 3:

public boolean even(int i) {
  if (i % 2 == 0) {
    return true;
  }
  return false;
}

根据用户指南,复杂度计算如下:“它是圈复杂度,也称为 McCabe 度量。每当一个函数的控制流分裂时,复杂度计数器就会加一。每个函数的最小复杂度为 1。” 在详细描述中提到,return 语句将复杂度值加一(如果它不是方法中的最后一条语句)。我不明白为什么 return 语句会拆分控制流。在我看来,控制流中的每个 return 语句之后只有一种可能的方式。

4

3 回答 3

3

您示例的控制流图包含 5 个边 (E)、5 个节点 (N) 和一个连接组件 (P)。

根据复杂度的定义(M=E-N+2P),正确的复杂度值为2。

于 2014-04-30T08:26:58.807 回答
0

这不是返回后的控制流,而是控制流在两个方法出口点之间分裂的事实。

考虑这两种方法:

public boolean isAdult(int age) {
  boolean overEighteen = false;
  if (i > 18) {
     overEighteen = true;
  }
  return overEighteen;
}

public boolean isAdultComplex(int age) {
  boolean overEighteen = false; // not used, but keeping methods identical
  if (i > 18) {
     return true;
  }
  return false;
}

如果循环复杂度计算没有为方法中的早期返回加一isAdultComplex,这两种方法将具有相同的循环复杂度。但是第二个肯定会更复杂,因为它有两个出口点。

在这样的短方法中,这个问题通常看起来微不足道,但想象一下在 150 行方法中的早期回报。在精神上跟随变得更加困难。

于 2014-04-30T09:11:45.137 回答
0

仅供参考,这个讨论与https://jira.codehaus.org/browse/SONARJAVA-75有关。我确实确认,SonarQube 报告的复杂性暂时混合了“循环复杂性”和“基本复杂性”。

于 2014-05-05T07:10:37.987 回答