我最近在SO上看到过一些与"代码指标"相关的问题,不得不想知道这些魅力是什么?以下是一些最近的例子:
什么代码指标让你相信提供的代码很糟糕
如果有多少行代码是一个有用的指标
写质量测试
在我看来,没有指标可以替代代码审查,但是:
某些指标有时可能表明需要审核的地方,以及
短时间内指标的根本变化可能表明需要审查的地方
但我想不出一个单独的指标本身总是表示"好"或"坏"代码 - 测量无法看到的东西总是有例外和原因.
从我忽略的代码指标中获得了一些神奇的洞察力吗?懒惰的程序员/经理是否在寻找不读代码的借口?人们是否提供了巨大的遗留代码库并寻找起点?这是怎么回事?
注意:我已经在答案和评论中询问了一些关于特定线程的问题并且没有得到回复,所以我认为我应该问整个社区,因为我可能错过了一些东西.运行一个指标批处理作业并不是真的必须再次阅读其他人的代码(或我自己的代码)会很好,我只是觉得它不实用!
编辑:我很熟悉大多数(如果不是所有)正在讨论的指标,我只是没有看到它们孤立或作为任意质量标准.
他们所说的话,这个帖子中的答案有点奇怪:
"团队",就像那些所述指标的"唯一受益者";
"指标",就像它们本身就意味着什么.
1 /指标不是针对一个人群,而是针对三个人群:
开发人员:他们关心的是瞬时 静态代码指标静态分析的(圈复杂度,评论质量,行数......)
项目负责人:他们关注来自单元测试,代码覆盖,持续集成测试的日常 实时代码指标
业务赞助商(他们总是被遗忘,但他们是利益相关者,为开发付费):他们关注有关架构设计,安全性,依赖性的每周 全球代码指标 ......
当然,所有这三个指标都可以观察和分析所有这些指标,但每种指标都被设计为每个特定群体都能更好地使用.
2 /度量标准本身代表快照代码,这意味着......什么都没有!
它是这些指标的组合,以及可能表示"好"或"坏"代码的那些不同分析级别的组合,但更重要的是,这些指标的趋势是重要的.
这就是重复这些指标将带来真正的附加价值,因为它们将帮助业务经理/项目负责人/开发人员在不同的可能代码修复中优先考虑
换句话说,您关于"指标的魅力"的问题可能指的是:
"漂亮"的代码(虽然这总是在旁观者编码器的眼中)
"好"代码(有效,可证明有效)
因此,例如,具有9的圈复杂度的函数可以被定义为"漂亮",而不是42的圈复杂度的一个长卷积函数.
但是,如果:
后一种功能具有稳定的复杂性,并且代码覆盖率达到95%,
而前者的复杂程度越来越高,而且覆盖率为...... 0%,
有人可能会说:
后者代表一个" 好 "的代码(它工作,它是稳定的,如果它需要改变,可以检查它是否仍然有效,修改后),
前者是一个" 坏 "代码(它仍然需要添加一些案例和条件来涵盖它所要做的所有事情,并且没有简单的方法来进行一些回归测试)
所以,总结一下:
一个单一的指标,它本身总是表明[...]
:不多,除了代码可能更"漂亮",这本身并不意味着很多......
从我忽略的代码指标中获得了一些神奇的洞察力吗?
只有指标的组合和趋势才能给出真正的"神奇洞察力".
我有一个项目,我作为一个人的工作在一个月前测量了圈复杂度.这是我第一次接触这些指标.
我得到的第一份报告令人震惊.几乎所有的功能都没有通过测试,即使是(imho)也非常简单.我通过将逻辑子任务移动到子例程中来解决复杂问题,即使它们只被调用一次.
对于另外一半的例程我作为程序员的骄傲踢了进去,我试图以他们做同样的方式重写它们,只是更简单,更易读.这很有效,我能够最大限度地降低客户的yclomatic复杂性门槛.
最后,我几乎总能找到更好的解决方案和更清晰的代码.性能没有受到这种影响(相信我 - 我对此很偏执,我经常检查编译器输出的反汇编).
我认为,如果您将指标用作改进代码的理由/动机,那么指标就是一件好事.知道何时停止并要求提供度量违规授权是非常重要的.
度量标准是指南和帮助,而不是目的本身.
我曾经使用的最佳指标是CRAP得分. http://www.artima.com/weblogs/viewpost.jsp?thread=215899
基本上,它是一种将加权的圈复杂度与自动测试覆盖率进行比较的算法.该算法如下所示:CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)
其中comp(m)是方法m的圈复杂度,cov(m)是自动化测试提供的测试代码覆盖率.
前面提到的文章的作者(请阅读它......非常值得你的时间)建议最大CRAP分数为30,其分解方式如下:
Method’s Cyclomatic Complexity % of coverage required to be below CRAPpy threshold ------------------------------ -------------------------------- 0 – 5 0% 10 42% 15 57% 20 71% 25 80% 30 100% 31+ No amount of testing will keep methods this complex out of CRAP territory.
正如您快速看到的那样,该指标奖励编写代码并不复杂,加上良好的测试覆盖率(如果您正在编写单元测试,而且您应该,并且不测量覆盖范围......好吧,您可能会喜欢吐痰到风中以及).;-)
对于我的大多数开发团队,我都非常努力地将CRAP得分低于8,但是如果他们有正当理由证明可以接受的复杂性是合理的,只要他们通过充分的测试来弥补复杂性.(编写复杂的代码总是很难测试......对这个指标来说是一种隐藏的好处).
大多数人发现很难编写能够通过CRAP分数的代码.但随着时间的推移,他们编写了更好的代码,代码更少的问题,代码更容易调试.在任何指标中,这是最少关注和最大利益的指标.
一个好的代码审查不能替代一个好的静态分析工具,它当然不能代替一套好的单元测试,如果没有一套验收测试,现在单元测试是不行的......
代码指标是放入工具箱的另一个工具,它们本身不是解决方案,它们只是一个适当使用的工具(当然还有所有其他工具!).
对我来说,识别错误代码的最重要指标是圈复杂度.我项目中的几乎所有方法都低于CC 10,并且在CC超过30的遗留方法中总是会发现错误.高CC通常表示:
用急速编写的代码(即,没有时间找到优雅的解决方案,而不是因为问题需要复杂的解决方案)
未经测试的代码(没有人为这些野兽编写测试)
经过多次修补和修复的代码(即带有ifs和todo注释的代码)
重构的主要目标
人们被理解和理解代码的机制方法所吸引.如果是真的,请考虑效率和生产力的后果!
我同意"代码优点"的指标与"好散文"的指标一样合理.然而,这并不意味着指标毫无用处,也许并未被滥用.
例如,某些指标的极值会指出可能出现的问题.1000线长的方法可能无法维护.零单元测试代码覆盖率的代码可能有更多的错误,类似的代码与大量的测试.在发布之前添加到项目中的代码的大幅跳跃可能不是第三方库会引起额外的关注.
我认为如果我们使用指标作为建议 - 一个红旗 - 也许它们可能是有用的.问题是当人们开始用SLOC测量生产率或质量测试线的百分比时.
我的高度主观意见是,代码指标表达了不可抗拒的制度迷恋,能够量化一些本质上无法量化的东西.
在某种程度上,至少在心理上是有道理的 - 你如何能够对你无法评估或理解的事情做出决定?当然,最终,你不能评估质量,除非你对这个主题有所了解(并且至少和你想要评估的那样一样好),或者问一个知识渊博的人,这当然只是把问题归咎于一步.
从这个意义上说,也许一个合理的比喻是通过SAT分数评估大学入学者,这是不公平的,并且错过了各种微妙之处,但如果你需要量化,你必须做点什么.
不是说我认为这是一个很好的衡量标准,只是我可以看到它的制度不可抗拒性.而且,正如您所指出的,可能有一些合理的指标(大量500多行方法,高复杂性 - 可能很糟糕).不过,我从来没有去过一个买入这个地方的地方.
我相信有一个代码指标.
我正在研究一个大系统.当我遇到一个新的要求时,我开始编写代码.当我完成并解决了错误后,我将其检入版本控制系统.该系统做了差异,并计算我所做的所有更改.
数字越小越好.
度量标准和自动化测试并不意味着可以替代完整的代码审查.
他们只是加快了速度.使用自动检查器,您可以轻松查看您忘记遵循的约定,使用指定的包和方法等.您可以在不使用其他人的时间的情况下查看可以修复的内容.
管理人员也喜欢衡量他们,因为他们觉得他们已经获得了生产力的确切数字(尽管通常情况并非如此),他们应该能够更好地兼顾人员.
测量仅在以下情况下有用:
团队开发了它们
团队同意了他们
它们被用于识别特定区域
一般而言,任何不适合的指标都会受到团队优化的影响.你想测量代码行吗?通过天哪,看看他们能写多少!你想测量代码覆盖率,通过golly,看我掩盖代码!
我认为指标对于识别趋势很有用,事实上,我已经看到了一些有用的指标,例如构建中断时的绘图,代码流失(整个项目中代码行数的变化)和其他事情.但如果团队没有提出他们,或者他们不同意或理解他们,那么你很可能处于一个受伤的世界.
以下是stan4j(http://stan4j.com/)的一些复杂性指标.
一个eclipse类结构分析工具.
我喜欢这个工具和指标.我将指标视为统计数据,指标,警告消息.有时由于某些方法或某些类确实有一些复杂的逻辑使它们变得复杂,应该做的是密切关注它们,检查它们是否需要重构它们或仔细检查它们,因为通常他们容易出错.我也使用它作为分析工具来学习源代码,因为我喜欢从复杂到简单的学习.实际上它还包括一些其他指标,如Robert C. Martin Metrics,Chidamber和Kemerer Metrics,Count Metrics但我最喜欢这个
复杂度指标
Cyclomatic Complexity Metrics
Cyclomatic Complexity(CC)方法 的圈复杂度是方法控制流图中决策点的数量增加1.决策点出现在if/for/while语句,case/catch子句和类似的源代码元素中,其中控制流不仅仅是线性的.由单个(源代码)语句引入的(字节代码)决策点的数量可以变化,这取决于例如布尔表达式的复杂性.方法的圈复杂度值越高,测试方法控制流图的所有分支所需的测试用例就越多.
平均Cyclomatic Complexity 应用程序,库,包树或包的所有方法的Cyclomatic Complexity度量的平均值.
胖度量标准 工件的Fat度量标准是工件的相应依赖关系图中的边数.依赖关系图类型取决于度量标准变量和所选工件:
Fat 应用程序,库或包树的Fat度量标准是其子树依赖关系图的边数.此图包含包树层次结构中的所有工件子项,因此还包括叶包.(要在Composition视图中查看相应的图形,必须禁用Structure Explorer的Flat Packages切换.如果所选工件是库,则必须启用Show Libraries切换,否则必须禁用它.)
包的Fat度量是其单位依赖图的边数.此图包含包的所有顶级类.
类的Fat度量是其成员图的边数.此图包含该类的所有字段,方法和成员类.(此图和Fat值仅在使用细节级别成员而不是类执行代码分析时可用.)
库依赖关系的胖(胖 - 库) 应用程序的胖依赖关系度量标准是其库依赖关系图的边数.该图包含应用程序的所有库.(要在"合成视图"中查看相应的图形,必须启用Structure Explorer的"显示库"切换.)
扁平包依赖性的胖(胖 - 包) 应用程序的扁平包依赖性度量指标是其扁平包依赖关系图的边数.此图包含应用程序的所有包.(要在合成视图中查看相应的图形,必须启用Structure Explorer的Flat Packages切换,并且必须禁用Show Libraries切换.)
库的胖平面包依赖度量度量是其扁平包依赖关系图的边数.此图包含库的所有包.(要在Composition视图中查看相应的图形,必须启用Structure Explorer的Flat Packages和Show Libraries切换.)
顶级类依赖关系的胖(胖 - 单位) 应用程序或库的顶级类依赖关系度量标准是其单元依赖关系图的边数.此图包含应用程序或库的所有顶级类.(对于合理的应用程序,它太大而无法可视化,因此无法在合成视图中显示.单元依赖关系图只能显示在包中.)