我一直在玩测量大代码库的圈复杂度。
Cyclomatic复杂性是通过程序源代码的线性独立路径的数量,并且有许多免费工具可供您选择。
结果很有意思但并不令人惊讶。也就是说,我知道最毛茸茸的部分实际上是最复杂的(评级> 50)。但我发现有用的是,在决定从哪里开始重构时,我可以指出为每个方法分配一个具体的“坏”数字。
你使用圈复杂度吗?您找到的最复杂的代码是什么?
答案 0 :(得分:37)
我们无情地重构,并使用Cyclomatic复杂性作为在我们的“命中列表”上获取代码的指标之一。 1-6我们没有标注复杂性(尽管可能因其他原因而受到质疑),7-9是值得怀疑的,除非另有证明,否则任何超过10的方法都被认为是坏的。
我们看到的最糟糕的是来自我们不得不接管的一些遗留代码中的一个怪异的if-else-if链。
答案 1 :(得分:18)
实际上,除了方法级阈值之外,还可以使用圈复杂度。对于初学者来说,一个高复杂度的大方法可以分解为几个复杂程度较低的小方法。但它真的改善了代码库吗?当然,所有这些方法名称的可读性都会提高一些。但总条件逻辑没有改变。总条件逻辑通常可以减少replacing conditionals with polymorphism。
我们需要一个仅通过方法分解不会变为绿色的指标。我称之为CC100。
CC100 = 100 *(代码库的总圈复杂度)/(总代码行数)
答案 2 :(得分:12)
对我来说这很有用,就像big-O有用一样:我知道它是什么,并且可以使用它来获得对方法好坏的直觉,但我不需要计算它适用于我所写的每一项功能。
我认为更简单的指标,如LOC,在大多数情况下至少同样好。如果一个功能不适合一个屏幕,那么它的简单程度几乎无关紧要。如果一个函数需要20个参数并产生40个局部变量,那么它的圈复杂度是否为1无关紧要。
答案 3 :(得分:7)
我们最近开始使用它。我们使用NDepend进行一些静态代码分析,并测量圈复杂度。我同意,这是识别重构方法的一种不错的方法。
可悲的是,我们已经看到我们的开发人员在离岸开发的一些方法的#200以上。
答案 4 :(得分:7)
在有一个可以很好地使用C ++模板和元编程技术的工具之前,它对我的情况没有多大帮助。无论如何只记得那个
“并非所有重要的事情都可以 测量,而不是所有可以做的事情 被测量计数“ 爱因斯坦
所以请记住通过人工过滤传递此类信息。
答案 5 :(得分:6)
当你看到它时,你会知道复杂性。这种工具的主要用途是标记代码的部分内容,这些代码可以引起你的注意。
答案 6 :(得分:4)
我经常测量代码的圈复杂度。我发现它可以帮助我找到做得太多的代码区域。有一个工具指出我的代码中的热点比读取数千行代码试图找出哪些方法不遵循SRP要少得多。
然而,我发现当我对其他人的代码进行圈复杂度分析时,当我在100年代找到具有圈复杂度的代码时,它通常会导致沮丧,焦虑和愤怒的感觉。是什么迫使人们编写有几千行代码的方法?!
答案 7 :(得分:3)
帮助识别重构的候选人很有帮助,但重要的是要保持自己的判断力。我会支持kenj0418的修剪指南范围。
答案 8 :(得分:2)
有一个名为CRAP4J的Java指标,它根据经验将圈复杂度和JUnit测试覆盖率结合起来,提出了一个指标。他一直在做研究,试图改进他的经验公式。我不确定它有多广泛。
答案 9 :(得分:1)
我有一段时间没有使用它,但在以前的项目中,它确实帮助识别了别人代码中的潜在问题点(当然不是我的!)
一旦找到要检查的区域,我很快就会发现数字问题(你会相信很多GOTOS!)还有逻辑和一些非常奇怪的WTF代码。
循环复杂性非常适合展示可能做得很多的领域,从而打破单一的责任原则。理想情况下,这些应该分解为多种功能
答案 10 :(得分:1)
我担心,对于我最喜欢这样的指标LPC的项目的语言,实际上并没有很多免费的工具来生成它。所以不,对我来说没那么有用。
答案 11 :(得分:1)
为kenj0418的点击列表值+1。
我见过的最糟糕的是275.还有一些超过200的其他人我们能够重构为更小的CC;他们仍然很高,但是让他们进一步排队。我们没有太多运气与275野兽 - 它(可能仍然是)一个if-和switch-语句的网络太复杂了。当他们决定重建系统时,唯一真正的价值是作为一个步骤。
我认为高CC的例外是工厂; IMO,他们应该有一个高CC,但只有他们只做简单的对象创建和返回。
答案 12 :(得分:1)
在understanding意味着什么后,我现在开始在“试用”的基础上使用它。到目前为止,我发现它很有用,因为通常高CC与Arrow Anti-Pattern密切相关,这使得代码更难以阅读和理解。我还没有一个固定的数字,但NDepend正在提醒5以上的所有内容,这似乎是研究方法的良好开端。
答案 13 :(得分:1)
是的,我们使用它,我发现它也很有用。我们有一个很大的遗留代码库来驯服,我们发现了很高的圈复杂度。 (387在一种方法!)。 CC将您直接指向值得重构的区域。我们在C ++代码上使用CCCC。
答案 14 :(得分:1)
Cyclomatic Complexity只是一种可以称为Fabricated Complexity的组合。前段时间,我写了一篇文章,总结了代码复杂性的几个方面: Fighting Fabricated Complexity
需要使用工具来有效地处理代码复杂性。 .NET代码的工具NDepend将允许您分析代码复杂性的许多方面,包括代码指标,如: 环形复杂性,嵌套深度,方法的内聚缺乏,测试覆盖率......
包括依赖关系分析,包括专用于询问的语言(Code Query Language),代码中的复杂内容以及编写规则?