什么是环复杂性?

我偶尔看到的一个术语是“环状复杂性”。 在这里,我看到了一些关于“如何计算语言X的CC”或“如何用最小量的CC来计算Y”的问题,但是我不确定我真的明白它是什么。

在NDepend网站上 ,我看到一个解释,基本上说:“一个方法中的决策数量,每个if,for,&&等等都给CC分数增加了+1”)是真的吗?这个不好吗?我可以看到,为了保持代码容易理解,可能需要保持if语句的数量相当低,但这真的是一切吗?

还是有一些更深层次的概念呢?

我不知道更深的概念。 我相信它通常在可维护性指数的背景下考虑。 一个特定方法中的分支越多,维护该方法操作(通常)的心智模型就越困难。

具有更高圈复杂度的方法在unit testing中也更难获得完整的代码覆盖。 (感谢Mark W !)

当然,这带来了可维护性的所有其他方面。 错误/回归的可能性等等。 不过,核心概念是非常简单的。

循环复杂度测量您必须执行一个代码块以不同参数执行的次数,以执行通过该块的每条path。 更高的计数是不好的,因为它增加了逻辑错误逃离testing策略的机会。

维基百科可能是你的朋友: 圈复杂度的定义

基本上,你必须把你的程序想象成一个图表,然后

复杂性(…)定义为:

 M = E − N + 2P 

哪里

  • M =圈复杂度,
  • E =图的边数
  • N =图的节点数
  • P =连接组件的数量

CC是一个概念,试图捕捉你的程序是多么复杂,它是如何testing它在一个整数。

 Cyclocmatic complexity = Number of decision points + 1 

决策点可能是你的条件语句,如if,if … else,switch,for循环,while循环等。

下图描述了应用程序的types。

  • 圆环复杂性在1 – 10被认为是正常的应用

  • 环复杂性在于11 – 20适度的应用

  • 圆环复杂性在于21 – 50危险的应用

  • 循环复杂性超过50不稳定的应用

是的,就是这样。 代码可以执行的path越多,必须testing的东西越多,出错的可能性也越高。

我听到的另一个有趣的点:

代码中具有最大缩进的位置应该具有最高的CC。 这些通常是确保testing覆盖率的最重要的领域,因为预计它们将更难以阅读/维护。 正如其他答案所指出的那样,这些也是确保覆盖范围的更困难的代码区域。

就是这样,这个想法是,一个低CC的方法有更less的分叉,循环等等,这些都使得一个方法更加复杂。 想象一下,用一个分析器来查看500,000行代码,并看到一些数量级更高的方法。 这让你可以专注于重构这些方法,以便更好地理解(高CC的错误率也很高)

圆形复杂性真的只是一个可怕的stream行语。 实际上,这是用于软件开发的代码复杂度的一种度量,以指出更复杂的代码部分(更可能是越野车,因此必须经过非常仔细和彻底的testing)。 你可以使用E-N + 2P公式来计算它,但是我build议你通过插件自动计算。 我听说过一个经验法则,你应该努力保持CC低于5,以保持代码的良好可读性和可维护性。

我刚刚在我的Java项目上进行了Eclipse度量插件的实验,它有一个非常好的简洁的帮助文件,当然这个文件将与您常规的Eclipse帮助相结合,您可以阅读关于各种复杂性度量和技巧和技巧的更多定义在改善你的代码。

考虑你的函数的控制stream图 ,从出口到入口有一个额外的边缘。 圈复杂度是我们可以在不将图分成两部分的情况下可以进行的最大切割次数。

例如:

 function F: if condition1: ... else: ... if condition2: ... else: ... 

控制流程图

控制stream程图

您可以直观地看到为什么链接图的圈复杂度为3。

例程中的每个决策点(循环,开关,if等等)实际上都归结为一个if语句。 对于每个if你有2个代码path可以采取。 所以第一个分支有2个代码path,第二个有4个可能的path,第三个有8个,等等。 至less有2 ** N个代码path,其中N是分支的数目。

这使得难以理解代码的行为,并且当N越过一些小的数字时testing它。

圆周复杂度基本上是一个度量指标,需要更多的可维护性的代码区域。 这基本上是对重构的一个input。 在避免深层嵌套循环,条件等方面,它肯定给出了代码改进区域的指示。

就是这样。 然而,“case”或“switch”语句的每个分支都倾向于计为1.实际上,这意味着CC 讨厌 case语句以及任何需要它们的代码(命令处理器,状态机等)。

目前提供的答案没有提到软件质量与圈复杂度的相关性。 研究表明,具有较低的圈复杂性度量标准应该有助于开发更高质量的软件。 它可以帮助提高可读性,可维护性和可移植性等软件质量属性。 通常应该尝试获得5-10之间的圈复杂性度量。

使用像圈复杂度这样的指标的原因之一是一般情况下,人类只能在大脑中同时追踪大约7(加或减2)条信息。 因此,如果您的软件过于复杂且具有多个决策path,则不太可能会看到软件的行为方式(即,它将具有较高的圈复杂度指标)。 这很可能会导致开发错误或bug的软件。 有关这方面的更多信息可以在这里find,也可以在维基百科find

使用控制stream程图来计算圈复杂度。 通过程序源代码的线性无关path的定量度量被称为循环复杂度(如果/ if else / for / while)