我不时看到的一个术语是“循环复杂性”。在这里,我看到了一些关于“如何计算语言 X 的 CC”或“我如何用最少的 CC 做 Y”的问题,但我不确定我真的理解它是什么。
在NDepend 网站上,我看到一个解释,基本上是说“方法中的决策数量。每个 if、for、&& 等都会在 CC“分数”上加 1。真的是这样吗?如果是,为什么是这很糟糕吗?我可以看到人们可能希望将 if 语句的数量保持在相当低的水平,以使代码易于理解,但这真的是一切吗?
还是有更深层次的概念?
我不时看到的一个术语是“循环复杂性”。在这里,我看到了一些关于“如何计算语言 X 的 CC”或“我如何用最少的 CC 做 Y”的问题,但我不确定我真的理解它是什么。
在NDepend 网站上,我看到一个解释,基本上是说“方法中的决策数量。每个 if、for、&& 等都会在 CC“分数”上加 1。真的是这样吗?如果是,为什么是这很糟糕吗?我可以看到人们可能希望将 if 语句的数量保持在相当低的水平,以使代码易于理解,但这真的是一切吗?
还是有更深层次的概念?
我不知道更深层次的概念。我相信它通常是在可维护性索引的背景下考虑的。特定方法中的分支越多,维护该方法操作的心理模型就越困难(通常)。
具有较高圈复杂度的方法也更难以在单元测试中获得完整的代码覆盖率。(感谢马克 W!)
当然,这带来了可维护性的所有其他方面。错误/回归/等等的可能性。不过,核心概念非常简单。
圈复杂度衡量您必须执行具有不同参数的代码块以执行通过该块的每条路径的次数。较高的计数是不好的,因为它增加了逻辑错误逃脱测试策略的机会。
Cyclocmatic complexity = Number of decision points + 1
决策点可能是您的条件语句,例如 if、if ... else、switch、for 循环、while 循环等。
下表描述了应用程序的类型。
圈复杂度为 1 – 10 被视为正常应用
圈复杂度位于 11 – 20 中等应用
圈复杂度在于 21 – 50 风险应用
圈复杂度超过 50 应用不稳定
是的,就是这样。您的代码可以采用的执行路径越多,必须测试的东西就越多,出错的可能性就越高。
我听到的另一个有趣的观点:
代码中缩进最大的地方应该有最高的 CC。这些通常是确保测试覆盖率的最重要领域,因为预计它们将更难阅读/维护。正如其他答案所指出的,这些也是确保覆盖率的更难的代码区域。
圈复杂度真的只是一个可怕的流行语。事实上,它是软件开发中用于指出更复杂的代码部分(更可能是错误的,因此必须非常仔细和彻底地测试)的代码复杂性的度量。您可以使用 E-N+2P 公式计算它,但我建议您通过插件自动计算它。我听说过一个经验法则,您应该努力将 CC 保持在 5 以下,以保持代码的良好可读性和可维护性。
我最近刚刚在我的 Java 项目中尝试了Eclipse Metrics 插件,它有一个非常好的简洁的帮助文件,它当然会与你的常规 Eclipse 帮助集成,你可以阅读更多关于各种复杂性度量和提示和技巧的定义关于改进你的代码。
就是这样,这个想法是,具有低 CC 的方法具有更少的分叉、循环等,这些都使方法更加复杂。想象一下,使用分析器查看 500,000 行代码,并看到一些方法的 CC 量级更高。这使您可以专注于重构这些方法以更好地理解(高 CC 具有高错误率也很常见)
例程(循环、开关、if 等)中的每个决策点本质上归结为等效的 if 语句。对于每一个if
,您都有 2 个可以采用的代码路径。因此,第一个分支有 2 个代码路径,第二个分支有 4 个可能的路径,第三个分支有 8 个,依此类推。至少有 2**N 个代码路径,其中 N 是分支数。
这使得理解代码的行为并在 N 超过某个小数字时对其进行测试变得困难。
到目前为止提供的答案没有提到软件质量与圈复杂度的相关性。研究表明,具有较低的圈复杂度指标应该有助于开发更高质量的软件。它可以帮助提高可读性、可维护性和可移植性的软件质量属性。一般来说,应该尝试获得 5-10 之间的圈复杂度度量。
使用圈复杂度等指标的原因之一是,一般来说,一个人只能在大脑中同时跟踪大约 7 条(正负 2)条信息。因此,如果您的软件过于复杂且具有多个决策路径,那么您不太可能能够可视化您的软件的行为方式(即,它将具有较高的圈复杂度度量)。这很可能会导致开发错误或漏洞百出的软件。更多信息可以在这里找到,也可以在Wikipedia上找到。
使用控制流图计算圈复杂度。通过程序源代码的线性独立路径的数量测量称为循环复杂度( if/ if else / for / while )
圈复杂度基本上是一种度量,用于找出需要更多注意以实现可维护性的代码区域。它基本上是重构的输入。在避免深度嵌套循环、条件等方面,它肯定给出了代码改进领域的指示。
就是这样。但是,“case”或“switch”语句的每个分支都倾向于计为 1。实际上,这意味着 CC讨厌case 语句以及任何需要它们的代码(命令处理器、状态机等)。
圈复杂度衡量软件单元的复杂程度。它衡量程序使用条件逻辑构造(If、while、for、switch 和 case 等)可能遵循的不同路径的数量。如果您想了解更多关于计算它的信息,这里是一个精彩的 youtube 视频,您可以观看https://www.youtube.com/watch?v=PlCGomvu-NM
它在设计测试用例时很重要,因为它揭示了程序可以采用的不同路径或场景。“为了具有良好的可测试性和可维护性,McCabe 建议程序模块的圈复杂度不应超过 10”(Marsic,2012 年,第 232 页)。
参考文献:Marsic., I.(2012 年 9 月)。软件工程。罗格斯大学。取自 www.ece.rutgers.edu/~marsic/books/SE/book-SE_marsic.pdf