最近我们的公司已经开始测量循环的复杂性(CC)的职能在我们的码每周一次的基础上,并报告其职能有所改善或恶化。因此,我们已经开始支付更多的注意CC的功能。

我读过CC可以非正式方式计算为1+数的决定点,在一个功能(例如如果声明,对于循环,选择等等),或者还有数条路径通的功能...

我理解,最简单的方法减少CC是利用提取的方法重构重复...

有些事情我不确定,例如什么是CC下列代码碎片?

1)

for (int i = 0; i < 3; i++)
    Console.WriteLine("Hello");

Console.WriteLine("Hello");
Console.WriteLine("Hello");
Console.WriteLine("Hello");

他们都做同样的事情,但并的第一个版本具有更高的CC因为声明?

2)

if (condition1)
    if (condition2)
        if (condition 3)
            Console.WriteLine("wibble");

if (condition1 && condition2 && condition3)
    Console.WriteLine("wibble");

假设的语言不会短路评价,例如,然后这两个代码碎片具有同样的效果...但是CC第一段较高,因为它有3个决定点,如果声明?

3)

if (condition1)
{
    Console.WriteLine("one");

    if (condition2)
        Console.WriteLine("one and two");
}

if (condition3)
    Console.WriteLine("fizz");

if (condition4)
    Console.WriteLine("buzz");

这两个代码碎片做不同的东西,但他们有相同的CC?或嵌套的,如果声明的第一段有更高的CC?即嵌套的,如果声明是精神上更复杂的理解,但是,反映在CC?

有帮助吗?

解决方案

  1. 是的。你的第一个示例具有一个决定点而你的第二个没有,所以第一次具有更高的CC。
  2. 是的-也许,你的第一个例子具有多种决定点,因此较高CC。(见下文解释。)
  3. 是的-也许。很明显他们有相同数量的决定点,但也有不同的方式计算出立方厘米,这意味着...

...如果你的公司是测量CC在一个特定的方式,然后你需要熟悉这种方法(希望他们使用的工具,要做到这一点).有不同的方式计算CC于不同的情况(情况下的发言,布尔经营者,等等), 但你应该得到同样的信息的指标不管什么公约》使用。

更大的问题是什么,其他人已经提到的,那你的公司似乎更侧重于CC于在码后面。在一般情况下,肯定的是,下面5个是巨大的,低于10良好,20以下是好的,21至50应该是一个警告标志,而50以上的,应该是一个很大的警告标志,但是这些都是指导的,不是绝对的规则。你也许应该审查的码的过程中,有一个CC50以上的,以确保它不仅仅是一个巨大堆的代码,但是也许有一个特定的原因的程序,编写方式,这是不可行的(对于任何原因的数字)重构。

如果你使用的工具,以重构代码,以减少CC,确保你了解什么工具都是这样做的,他们并不只是转移的一个问题,另一个地方。最终,你希望你的代码有几个缺陷,正常工作,并且可以比较容易的维护。如果那个代码还有一个低CC、良好。如果你的代码符合这些标准和具有CC上述10,也许是时候坐下来与任何管理可以保卫你的代码(也许让他们检查他们的政策)。

其他提示

在浏览维基百科条目和Thomas J. McCabe的原始论文后,似乎您上面提到的项目是指标的已知问题。

但是,大多数指标确实有利有弊。我想在一个足够大的程序中,CC值可能指向代码的可能复杂的部分。但是,更高的CC并不一定意味着复杂。

与所有软件指标一样,CC并不完美。在足够大的代码库上使用,它可以让您了解可能是一个有问题的区域。

这里要记住两件事:

  1. 足够大的代码库:在任何非平凡的项目中,您将拥有具有非常高CC值的函数。如果在你的一个例子中,CC将是2或3,那么无关紧要。具有CC超过300的CC的功能肯定是要分析的东西。如果CC是301或302,则无关紧要。
  2. 别忘了用你的头。有些方法需要很多决策点。通常它们可以以某种方式重构以减少,但有时它们不能。不要使用像<!>这样的规则;使用CC <!> gt重构所有方法; XY <!> QUOT ;.看看它们并用你的大脑来决定做什么。
  3. 我喜欢每周分析的想法。在质量控制方面,趋势分析是一种非常有效的工具,用于识别在创建过程中的问题。这比等到它们变得如此之大以至于变得明显要好得多(参见 SPC )一些细节)。

CC不是衡量质量的灵丹妙药。显然,重复的陈述不是<!>“;更好的<!>”;而不是循环,即使循环具有更大的CC。循环有一个更大的CC的原因是有时它可能会被执行,有时它可能没有,这导致两个不同的<!>“情况<!>哪个都应该测试。在你的情况下,循环将总是执行三次,因为你使用常量,但CC不够聪明,无法检测到它。

与示例2中的链接ifs相同 - 此结构允许您拥有一个仅在condition1和condition2为true时才会执行的语句。这是一种特殊情况,在使用<!> amp; <!> amp;的情况下是不可能的。因此即使你不在代码中使用它,if-chain对特殊情况也有更大的潜力。

这是盲目应用任何指标的危险。 CC指标当然具有很多优点,但与其他任何改进代码的技术一样,它无法与上下文分离。将您的管理层指向Casper Jone关于代码行测量的讨论(希望我能为您找到一个链接)。他指出,如果代码行是衡量生产力的一个很好的指标,那么汇编语言开发人员就是地球上最具生产力的开发人员。当然,他们没有比其他开发者更高效;它只需要他们更多的代码来完成更高级别的语言用更少的源代码做的事情。正如我所说的,我提到了这一点,因此您可以向管理人员展示在没有智能审查指标告诉您的情况下盲目应用指标是多么愚蠢。

我建议如果他们不这样做,那么您的管理层会明智地使用CC测量作为一种方法来发现代码中应该进一步审查的潜在热点。盲目地针对低CC的目标而不参考代码可维护性或其他良好编码的措施是愚蠢的。

圈复杂程度类似于温度。他们都是测量,并且在大多数情况下没有意义的上下文。如果我说外面的温度是72度,这并不意味着多;但是,如果我加入这样的事实,我是在北极,72号变得显着。如果有人告诉我一种方法有一个圈复杂度的10,我不能确定如果是好的或坏的是没有它的上下文。

当我的代码审查现有的应用程序,我找到圈复杂性的一个有用的"起点"的指标。第一件事我检查的方法与CC>10.这些">10"方法并不一定是坏事。他们只是我提供一个起点,为在审查的码。

一般规则时考虑CC号:

  • 之间的关系CC#和测试中,应CC# <=#测试
  • "重构"对于CC#如果只会增加 维护性
  • CC上述10个经常表示一个或更多 代码的气味

[关闭主题]如果你喜欢可读性超过指标中的良好分数(是J.Spolsky说,<!>“什么是测量,得到完成<!>”? - 意味着指标被滥用更频繁我认为通常更好的方法是使用一个名称很好的布尔来替换复杂的条件语句。

然后

if (condition1 && condition2 && condition3)
    Console.WriteLine("wibble");

成为

bool/boolean theWeatherIsFine =  condition1 && condition2 && condition3;

if (theWeatherIsFine)
    Console.WriteLine("wibble");

我不是这个主题的专家,但我想我会给我两分钱。也许这就是值得的。

Cyclomatic Complexity似乎只是寻找潜在(但不是绝对)有问题的代码片段的特定自动化快捷方式。但是不是要解决的真正问题之一吗?代码需要多少个测试用例?如果CC较高,但测试用例数相同且代码更清晰,请不要担心CC。

1。)那里没有决策点。通过该程序只有一条路径,两个版本中只有一条可能产生结果。第一个更简洁,更好,Cyclomatic Complexity被诅咒。

两个测试用例

2。)在这两种情况下,你要写<!>“wibble <!>”;或者你没有。

两个测试案例

3。)第一个可能没有结果,<!>“一个<!>”,或者<!>“一个<!>”;和<!>“一个和两个<!>”; 3条路径。第二个可能导致两者中的任何一个或两者都没有。 4条路径。

第一个3个测试用例 第二个4个测试用例

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top