我的代码的“循环复杂性”是什么意思?


42

我是静态分析代码的新手。我的应用程序的圈复杂度为17,754。该应用程序本身只有37,672行代码。可以说基于代码行的复杂度很高吗?圈复杂性到底对我说了什么?


这完全取决于您在做什么。如果您尝试做一些简单的事情,那么它会非常非常高。例如,您不应在“ hello world”中具有该比例。
cwallenpoole 2011年

Answers:


48

圈复杂性到底对我说了什么?

循环复杂度不是代码行的度量,而是通过模块的独立路径的数量。您的循环复杂度为17,754,这意味着您的应用程序具有17,754条唯一的路径。这有一些含义,通常是在理解和测试您的应用程序有多困难方面。例如,假设编写良好的测试,则循环复杂度是达到100%分支覆盖率所需的测试用例数。

维基百科关于圈复杂度的文章可能是一个很好的起点。它具有几个伪代码片段和一些图形,这些图形显示了圈复杂性的全部含义。如果您想了解更多信息,还可以阅读McCabe的论文,其中他定义了圈复杂度

我的应用程序的循环复杂度为17,754行代码。该应用程序本身只有37,672行代码。凭代码行说复杂性高是正确的吗?

一点也不。在循环中嵌套很少的代码行和大量条件的应用程序可能具有极高的循环复杂性。另一方面,条件很少的应用程序的循环复杂度可能较低。这大大简化了它,但我认为它使想法得以传播。

在不了解您的应用程序做什么的情况下,具有较高的圈复杂度可能是正常的。我建议在类或方法级别上而不是仅在应用程序级别上测量圈复杂度。我认为,从概念上讲,这有点可管理-与通过大型应用程序的路径相比,使方法的路径可视化或概念化更容易。


36

循环复杂度是一种确定是否需要重构代码的方法。分析代码并确定复杂度数。复杂度由分支(如果语句等)确定。复杂度还可能考虑到循环等的嵌套以及其他因素,具体取决于所使用的算法。

该数字在方法级别很有用。在更高级别上,它只是一个数字。

17,754的数字表示项目级别的复杂性(总代码),没有太大的意义。

深入研究类和方法级别的复杂性将确定需要重构为较小方法或重新设计以消除复杂性的代码区域。

CASE以一种方法考虑一个包含50个案例的陈述。也许每个州都有不同的业务逻辑。这将产生50的圈复杂度。有50个决策点。可能必须使用工厂模式来重新设计CASE语句,以摆脱分支逻辑。有时您可以重构(将方法分解为较小的部分),在某些情况下,仅重新设计可以降低复杂性。

通常,对于方法级别的复杂性:

  • <10易于维护
  • 11-20难以维护
  • 超过21个用于重构/重新设计的候选人

还应考虑到更高的复杂度使代码更难进行单元测试。

我在单个方法上看到的最高复杂度是560。在一个方法中,大约有2000行if语句。基本上是无法维护的,无法测试的,充满了潜在的错误。想象一下分支逻辑所需的所有单元测试用例!不好。

尝试将所有方法保持在20以下,并意识到重构任何方法以降低其复杂性都需要付出代价。


这是一个更好的答案。
Pacerier,2015年

2
@Pacerier在这种情况下,只需增加答案;)。
2015年

>“总的来说,对于方法级别的复杂性”?
Benny Bottema

McCabe的原始应用程序之一是限制程序开发过程中例程的复杂性。他建议,程序员应该算他们正在开发的模块的复杂性,并把它们分割成更小的模块,每当模块的圈复杂度超过了10
乔恩·雷诺

“ CASE语句可能必须使用工厂模式进行重新设计,以摆脱分支逻辑。” 为什么?那并不能消除逻辑的复杂性。它只是将其隐藏起来,使其不那么明显,因此更难以维护。
梅森惠勒

1

它是您的应用程序中不同路径的数量。查阅有关CC的这篇IBM文章。

看起来很高,但是对于您而言,这是所有类和方法的所有方法的CC的加法。因为我不知道您的代码的结构,所以我的示例很费力,但是您可能还拥有一个包含37672行代码的怪兽方法或具有10行代码的3767方法。我的意思是,在应用程序级别,此指示器的意义不大,但是在方法级别,它可以帮助您将代码优化/重写为较小的方法,以使它们不易出错。

我个人经常阅读的内容是CC大于10的方法存在较高的缺陷风险。

我使用Sonar来测试应用程序的代码质量,默认情况下,如果您使用+10 CC的方法,它会发出警告。但这仍然没有任何意义。一个具体的例子:如果您使用Eclipse来equals基于bean的属性生成一种方法,那么CC将很快超过屋顶...


1
PMD的默认设置是警告圈速复杂度也为10。按方法级别查看复杂性还可以让您忽略可能具有较高CC的充分理由的equals方法,例如生成的方法。
Thomas Owens

我不确定,所以我检查了一下,但是Sonar内部使用PMD来获得此度量。所以这一切都说得通:-)
Jalayn 2011年

-1

它取决于您使用的工具。那里的一些开源工具将类作为模块,或将其他层次的结构作为模块。因此,项目越大,其趋向复杂性就越高。但是,以我个人的理解,它应该基于功能。由于项目规模越大,其参与的功能就越多。

我建议您使用名为Lizard的工具,您可以找到资源代码并从github下载zip文件。如果您的代码中没有太多机密信息,它也具有在线版本。

您应该关注的有意义的CCN基于其他功能。另外,将每个功能的CCN保持在15便是理想范围。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.