Answers:
“通过代码行来衡量软件生产率就像通过衡量飞机的重量来衡量飞机的进度。”-比尔·盖茨
看一下Jeff在该主题上的帖子:
Joel也有一篇古老但不错的文章,与软件指标密切相关,我强烈建议阅读: Econ 101管理方法
对我而言,关键点是引用Jeff: “负责任地使用指标与首先收集它们一样重要。”
使我对代码指标感到困惑的是,它做得还不够。大多数公司都会报告其员工,供应商和系统的效率,但是似乎没有人愿意报告代码。我肯定会同意这样的答案:陈述更多的代码行是一种责任,但是您的代码所做的却更为重要。
代码行: 正如我已经提到的,这是一项至关重要的度量,应该在每个级别上都认真对待。函数,类,文件和接口可以指示长期难以维护且成本高昂的所有代码。比较代码的总行数和系统的工作量是无限困难的。它可能做很多事情,在这种情况下,将有很多行代码!
复杂性: 这项度量很适合在您尚未使用的代码库上进行,并且可以很好地指示问题所在的位置。作为一个有用的轶事,我在自己的一个代码库中测量了复杂度,而最复杂的区域是我在更改时花费最多的时间。降低复杂性的努力大大减少了维护时间。如果管理人员手头有这些度量,他们可以计划系统特定区域的重构迭代或重新设计。
代码重复: 就我而言,这是非常重要的度量。代码重复是一个非常糟糕的信号,它可能会指出系统设计水平低下的严重问题,或者指出复制粘贴的开发人员,从长远来看会导致大量问题,而系统则难以维护。
依赖性图 查找不良的依赖性和循环的依赖性是代码中的一项重要度量。这几乎总是指向需要修改的不正确的高级设计。有时,一个依赖关系会吸收很多不必要的其他依赖关系,因为有人在电子邮件库中使用addNumber进行财务计算。更改电子邮件库和财务中断后,每个人都会感到震惊。如果一切都取决于一件事,那么它也可以指向所有难以维护且设计不当的库。
良好的度量始终可以告诉您系统的每个功能都占用很小的空间。更少的依赖关系,更少的复杂性,更少的重复。这表明耦合松散和内聚性高。
这种“源代码指标”废话不会消失吗?
原始代码行(SLOC)是最古老,最简单,最基本的指标。
Halstead最初提出了一整套指标。许多人在编写测量程序之前都玩得很开心,直到一些剧透进行了明显的研究,并证明了每个Halstead指标都与SLOC密切相关。
那时,Halstead的指标被放弃了,因为SLOC总是更容易测量。
据我所知,发现的错误数量与代码行(可能搅动),模语言,程序员和领域直接相关。
我不知道与错误紧密相关的任何其他简单而实用的指标。
我想做的一件事是开始运行我所从事的不同项目的数字-Test Coverage :: kLOC,然后讨论“感知质量”以查看是否存在相关性。
仅当您知道如何处理所获得的答案时,指标才有用。本质上,软件指标就像温度计。直到您知道正常温度是多少,您在98.6°F的温度下测量的事实才有意义。上面的温度对人体温度有好处,但对冰淇淋却很不利。
常见的指标,可以成为有用的是:
前两个度量趋势。您发现错误的速度超过了解决它们的速度?有两种可能的结果:也许我们需要更多的资源来修复错误,也许我们需要停止实施新功能,直到我们赶上来。后两者提供了您完成工作有多接近的图片。敏捷团队将其称为“疲倦”图表。
圈复杂度是一个有趣的指标。它的基本概念是函数/方法中唯一执行路径的数量。在繁重的单元测试环境中,这对应于验证每个执行路径所需的测试数量。但是,仅因为您具有Cyclomatic Complexity为96的方法,并不意味着它一定是错误的代码-或您必须编写96个测试以提供合理的置信度。生成的代码(通过WPF或解析器生成器)创建这种复杂的代码并不少见。可以粗略地了解调试方法所需的工作量。
底线
您进行的每次测量都需要定义以下内容,否则将无用:
您所采用的指标可能因项目而异。您可能在整个项目中使用了一些指标,但是“正常”的定义会有所不同。例如,如果一个项目平均每周发现5个错误,而新项目每周发现10个错误,则不一定表示有问题。这次可能只是测试团队更加细致。同样,“正常”的定义可能会在项目的整个生命周期内发生变化。
该指标只是一个温度计,您该如何处理取决于您自己。
源代码是负债,而不是资产。考虑到这一点,测量代码行类似于跟踪建造房屋时花费的美元。如果您想使预算保持在预算之内,则需要完成此操作,但是您不一定会认为每天花费1000美元比每天花费50美元更好。您想知道有多少钱用来盖房子。软件项目中的代码行也是如此。
简而言之,没有用于源代码的有用指标,因为仅测量源代码本身就没有用。
由于源代码只是序列,选择和重复的组合。如果要描述我们可以合理预期生产的最佳软件,则如下所示。具有几乎100%的测试代码覆盖率的软件,使用该工作所需的最少代码行数,但又足够灵活以承受更改。
揭示为什么KLOC计数对评估性能没有用(甚至有害)的原因。
几年前,我参与了一个大型项目(公司中有70多名员工,客户中有30多名员工),该项目使用KLOC计数作为衡量团队和个人绩效的唯一标准。
为了我们的Y2K工作(告诉您它是多久以前的:)),我们对团队负责的代码部分进行了大幅度的清理。我们最终发布了大约30.000行代码,对于5个人来说,这是一个不错的3个月的工作。我们最终还废弃了另外70.000行代码,这是3个月工作的出色表现,尤其是与新代码结合使用时。
该季度的最终结果:-40.000行代码。在本季度之后的性能评估期间,由于未能满足我们每季度生产20.000行代码的生产力要求(毕竟,这些工具表明我们生产了-40.000行代码),我们受到公司的正式谴责。如果没有项目经理和质量保证团队的干预,得到了谴责的推翻并被表扬,那么我们所有人都将被列为表现不佳并被绕过晋升,培训,加薪等工作。
几个月后(这些事情需要时间),我们被告知该公司正在审查其生产力标准,并雇用了一个专家团队根据功能点分析创建新系统。
我很惊讶没有人提到单元测试的声明/决策覆盖率(单元测试所执行代码的百分比)。
代码覆盖率很有用,因为您知道应用程序的百分之几不会灾难性地失败;其余的有用性取决于单元测试的质量。
通常,提交越小越好。这是关于SCM工具的,而不是本质上的代码,但这是一个非常可衡量的指标。提交越小,越容易将每个更改视为一个原子单位。还原特定更改并在出现问题时查明位置越容易。
只要没有提交破坏构建...
我经常使用巨大的C ++程序包,并且在寻找有问题的代码值得重构Cyclomatic Complexity或可怕的FanIn / FanOut时,通常会寻找它们。解决那里的问题通常会导致整个代码库的改进。
当然,这些数字只能作为值得一看的提示。在无法通过构建或拒绝提交之后设置此硬阈值将是荒谬的。
在我的工作中,很多情况下我都使用代码指标:
在编写代码时
我日常工作中最大,也许最重要的用途是Checkstyle,这是Java开发人员的工具,它会根据我们定义的一组规则不断检查代码的指标(除其他外),并标记代码未包含的地方遵守这些规则。在我开发代码时,它实时地告诉我我的方法是变长,变复杂还是耦合,使我退后一步,然后考虑将其重构为更好的方法。
开发人员可以完全自由地违反所有规则,因为它们永远不会适用于所有情况。那里的“规则”可以激发思想并说:“嘿,这是最好的方法吗?”
质量检查/代码审核期间
当我执行代码审查时,我通常要做的第一件事是结合使用代码覆盖工具来检查我正在审查的代码的代码覆盖率,该工具会突出显示已覆盖了哪些代码行。这使我对测试代码的完整性有一个大致的了解。我并不在乎覆盖率是20%还是100%,只要对重要代码进行了良好的测试即可。因此,所覆盖的百分比多少没有意义,但0%的确定性就像我要仔细查看的拇指酸痛一样突出。
我还检查团队同意的哪些指标已“破坏”(如果有),以查看我是否同意开发人员的观点,或者是否可以提出改进建议。我们的团队已同意这些开发指标来编写新代码,这为改进我们的代码做出了巨大努力。我们编写的整体方法要少得多,现在在单一责任原则上要好得多。
对遗留代码进行趋势改进的趋势 我们有许多遗留代码需要改进。在任何时间点的指标都没有用,但是对我们来说重要的是随着时间的流逝,代码覆盖率会上升,而复杂性和耦合性等因素则会下降。因此,我们的指标已插入到我们的持续集成服务器中,从而使我们可以花时间查看以确保我们走上正确的轨道。
掌握新的代码库 关于我不熟悉的代码库,是我唯一一次使用源代码度量标准的行。与我合作过的其他项目相比,它使我能够快速评估项目的粗略规模。使用其他指标,我也可以对项目质量有一个更粗略的了解。
关键是要使用指标作为趋势,讨论或前进方向的起点,而不是认真地将其管理成精确的数字。但是我坚信,如果正确使用它们,它们可以帮助您改进正确的代码。
切记:所有代码至少可以减少1条指令。所有代码至少有1个错误。因此,所有代码都可以简化为一条无效的指令。希望有帮助!