你觉得圈复杂性是一个有用的措施?
我一直在测量一个大代码库的圈复杂度。
循环复杂性是通过程序源代码的线性独立path的数量,有许多免费的工具供您select。
结果是有趣的,但并不奇怪。 也就是说,我所知道的最有趣的部分实际上是最复杂的(评分> 50)。 但是我发现有用的是每个方法都有一个具体的“坏”数字,这个数字是我在决定从何处开始重构的时候可以指向的。
你用循环复杂吗? 什么是你find的最复杂的代码?
我们毫不留情地进行重构,并将Cyclomatic复杂性作为获取我们“命中列表”上的代码的指标之一。 我们没有提到复杂性(虽然可能会因为其他原因而被质疑),7-9是有问题的,任何超过10的方法都被认为是不好的,除非另有certificate。
我们所看到的最糟糕的情况是,我们必须接pipe一些遗留代码中的一个怪异的if-else-if链。
实际上,圈复杂度可以超越方法级别的阈值。 对于初学者来说,一个高复杂度的大方法可能会被分解成几个小的方法,而且复杂度较低。 但它真的改善了代码库吗? 当然,所有这些方法的名称都可以使得可读性更好一些。 但总的条件逻辑没有改变。 总的条件逻辑通常可以通过用多态来代替条件来减less。
我们需要一种不仅仅是方法分解而变成绿色的度量。 我称之为CC100 。
CC100 = 100 *(码基总循环复杂度)/(总码行数)
对我来说这很有用,就像big-O是有用的一样:我知道它是什么,可以用它来得到一个方法是好还是坏的直觉,但是我不需要为每个方法计算它函数我写了。
我认为更简单的指标,如LOC,在大多数情况下至less是一样的。 如果一个function不适合在一个屏幕上,它几乎无所谓。 如果一个函数需要20个参数并且产生40个局部variables,那么它的圈复杂度是1就没有关系。
我们最近开始使用它。 我们使用NDepend做一些静态代码分析,并测量圈复杂度。 我同意,这是一个体面的方法来确定重构的方法。
不幸的是,我们已经看到了我们的开发者在海外创build的一些方法在200以上。
在C ++模板和元编程技术之前,有一种工具可以很好地工作,在我的情况下没有多大的帮助。 无论如何只要记住这一点
“并不是所有的东西都可以被测量,并不是所有的东西都可以被测量”爱因斯坦
所以记得通过人工滤波来传递这种types的任何信息。
当你看到它时你会知道复杂性。 这种工具的主要function是标记正在逃避你注意的代码部分。
我经常测量我的代码的圈复杂度。 我发现它可以帮助我发现代码太多的地方。 有一个工具指出我的代码中的热点,比读取数千行代码试图找出哪些方法没有遵循SRP要花费更多的时间。
但是,我发现当我对其他人的代码进行复杂度分析的时候,当我在100年代find复杂的循环代码的时候,通常会感到沮丧,焦虑和愤怒。 什么迫使人们写出几千行代码的方法?
帮助确定重构的候选人是很好的,但重要的是保持你的判断。 我会支持kenj0418修剪指南的范围。
有一个名为CRAP4J的Java度量标准,它将循环复杂度和JUnittesting覆盖率经验地结合起来,形成一个度量标准。 他一直在研究尝试和改进他的经验公式。 我不确定它有多广泛。
我有一段时间没有使用它,但是在之前的项目中,它确实帮助识别了某些代码中的潜在故障点(当然不会是我的!)
在find这个区域的时候,我很快发现了一些很奇怪的问题(还有很多GOTOS,你会相信!),还有一些非常奇怪的WTF代码。
圆形复杂性对于显示可能做得太多的区域是很好的,因此打破了单一责任原则。 理想情况下,这应该被分解成多个function
恐怕对于我最喜欢这个指标的项目语言来说, LPC实际上并没有很多免费的工具来生产它。 所以不,对我没那么有用。
+1为kenj0418的命中列表值。
我见过的最差的是275.另外还有200多人,我们可以重构为更小的CC; 他们仍然很高,但是让他们进一步推进。 我们对这只野兽并没有太多的好运 – 这是(可能还是)一个if-and switch-statement的networking,太复杂了。 当他们决定重build系统的时候,只有真正的价值才是一个突破。
我对此感到满意的高消费产品的例外是工厂; 海事组织,他们应该有一个高CC,但只有他们只是做简单的对象创build和返回。
在理解了它的意思后,我现在开始在“试用”的基础上使用它。 到目前为止,我发现它是有用的,因为通常高CC与箭头反模式 ,这使得代码难以阅读和理解携手。 我还没有一个固定的数字,但是NDepend对于5以上的所有事情都是警觉的,这对于调查方法来说是一个很好的开始。
是的,我们使用它,我也发现它也很有用。 我们有一个很大的遗留代码基地来驯服,我们发现高回圈复杂性。 (387在一个方法!)。 CC直接指向那些值得重构的区域。 我们在C ++代码上使用CCCC。
回旋复杂性只是一种可称之为“制造复杂性”的组成。 前一阵子,我写了一篇文章来总结代码复杂性的几个维度: 战斗制造的复杂性
在处理代码复杂性时,需要加工工具。 用于.NET代码的工具NDepend将允许您分析代码复杂度的许多维度,包括代码度量,例如:循环复杂度,嵌套深度,缺less方法的凝聚力,testing的覆盖率…
包括依赖关系分析和包含一个语言( 代码查询语言 ),专门提出问题,在我的代码中是什么复杂的,并写规则?