软件度量——有用的工具还是浪费时间?对于每一位珍视这些软件系统数学抽象的开发者来说,都有一位开发者认为软件度量仅仅是为了让项目经理忙碌而发明的。软件度量可能是非常有力的工具,可以帮助实现您的目标,但正确使用它们非常重要,因为它们也可能使项目团队失去动力,并将开发引导到错误的方向。
在过去的 11 年中,Software Improvement Group 基于软件度量为数百家组织提供了关于软件开发和风险管理的建议。我们在 200 多项调查中使用过软件度量,在这些调查中,我们检查了系统的单个快照。此外,我们还使用软件度量来跟踪 400 多个系统的持续开发工作。在这些项目的过程中,我们了解到在使用软件度量进行项目管理时应避免的一些误区。本文讨论了其中最重要的四个
• 孤立地使用度量
• 过分关注度量
• 片面度量
• 度量泛滥
了解这些误区将帮助您识别它们,并有望避免它们,这将有助于您的项目取得成功。作为一名软件工程师,您对这些误区的了解将帮助您理解项目经理为何要使用软件度量,并在经理们以低效的方式应用度量时协助他们。作为一名外部顾问,您在提出建议时需要考虑到这些误区。最后,如果您正在软件度量领域进行研究,了解这些误区将帮助您在向从业人员展示您的新度量时将其置于上下文中。在深入探讨这些误区之前,让我们先看看为什么软件度量可能有用。
“衡量什么,得到什么。” 这句话绝对适用于软件项目团队。无论您将什么定义为度量,只要它被用来评估团队,度量的值就会朝着期望值移动。因此,为了实现目标,您可以持续衡量期望目标的属性,并将这些测量值绘制在团队可见的地方。理想情况下,期望目标与当前测量值一起绘制,以指示与目标的距离。
想象一个项目,其中特定用例的运行时性能至关重要。在这种情况下,创建一个测试来每日测量用例的执行时间会有所帮助。通过将每日数据点与期望值进行比较,并确保团队看到此测量值,每个人都可以清楚地了解目标是否正在实现,或者最近的开发行动是否正在使团队偏离目标。
即使这看起来很简单,这种技术也可能以多种微妙的方式被错误地应用。例如,想象这样一种情况:客户不满意,因为他们报告的产品问题没有得到及时解决。为了提高客户满意度,项目团队跟踪一个版本中问题的平均解决时间,理由是较低的平均解决时间可以提高客户满意度。
不幸的是,现实并非如此简单。首先,更快地解决问题可能会导致不良的副作用——例如,现在的快速修复可能会因为技术债务的产生而导致以后更长的修复时间。其次,如果这些修复每年只发布一次,那么在几天内解决问题对客户没有任何帮助。最后,当根本不需要修复时,客户无疑会更满意——也就是说,问题一开始就不会出现在产品中。
因此,使用度量可以让您朝着目标前进,这个目标可以是高层次的业务主张(“维护此系统的成本不应超过每年 10 万美元”)或更具技术性的目标(“所有页面应在 10 秒内加载完成”)。不幸的是,使用度量也可能阻碍您实现期望的目标,这取决于遇到的误区。在本文的其余部分,我们将讨论我们经常遇到的一些误区,并解释如何识别和避免它们。
软件度量可以在软件系统的不同视图上进行测量。本文重点关注在系统的特定代码库版本上计算的度量,但这些误区也适用于在其他视图上计算的度量。
假设代码库仅包含当前项目的代码,则软件产品度量建立了一个真实的基础。然而,仅计算度量是不够的。还需要两个操作来解释度量的值:添加上下文;以及建立与目标的关系。
为了说明这些要点,我们使用 LOC(代码行数)度量来提供有关项目当前规模的详细信息。即使对于代码行的构成有多种定义,这样的度量也可以用来推断所检查的代码库是否完整,或者是否包含无关的代码,例如复制进来的库。然而,要做到这一点,度量应该置于上下文中,这引出了我们的第一个误区。
在没有适当解释的情况下使用度量。表现为无法解释度量的给定值意味着什么。可以通过将度量置于与目标相关的上下文中来解决。
单个度量数据点的用处是有限的。知道一个系统有 10 万行代码本身毫无意义,因为这个数字本身并不能解释系统是大还是小。为了有用,度量的值应该例如与项目历史记录或其他项目的基准数据点进行比较。在第一种情况下,您可以发现应该由外部事件解释的趋势。例如,图 1 中的图表显示了从 2010 年 1 月到 2011 年 7 月的软件系统的 LOC。
这里首先想到的问题是:“为什么系统的大小在 2010 年 7 月下降了这么多?” 如果这个问题的答案是“我们删除了早期复制进来的大量开源代码”,那么就没有问题(除了首先包含这些代码)。如果答案是“我们不小心删除了部分代码库”,那么引入不同的源代码版本管理方法可能是明智之举。在这种情况下,答案是计划采取一项行动来大幅减少所需的配置;鉴于删除的代码量,这项行动显然是成功的。
请注意,将度量置于上下文中的好处之一是,它允许您专注于图表的重要部分。关于在某个时间点发生了什么,或者为什么该值与其他系统显着偏离的问题,比关于如何测量度量的具体细节更重要。通常,人们有意或无意地试图将讨论引导到“这个度量是如何测量的?”而不是“这些数据点告诉我什么?” 在大多数情况下,度量的确切构造对于从数据中得出的结论并不重要。例如,考虑图 2 和图 3 中显示的三个图,它们代表计算系统规模的不同方式。图 2 显示了代码行数,计算为每行包含至少一个非注释或空格字符的行(橙色)和代码行数,计算为所有换行符(蓝色)。图 3 显示了使用的文件数。
趋势线表明,即使比例不同,这些规模度量都显示了相同的事件。这意味着这些度量中的每一个都是将系统规模与其他系统进行比较的良好候选者。只要其他系统的规模以相同的方式测量,从数据中得出的结论将非常相似。
不同的趋势线提出了第二个问题:“为什么规模在一段增加的时期后会减少?” 答案可以在对该特定系统进行更改的正常方式中找到。当系统规模增加时,会安排一项行动来确定是否有可能进行新的抽象,通常情况下是可能的。这种类型的重构可以显着减小代码库的大小,从而减少维护工作量,并使向系统添加功能变得更容易。因此,这里的目标是通过(除其他外)保持代码库相对较小来减少维护工作量。
在理想情况下,期望的目标(例如,减少维护工作量)和度量(例如,小代码库)之间存在直接关系。在某些情况下,这种关系是基于非正式推理的(例如,当系统的代码库很小时,更容易分析系统做什么);在其他情况下,科学研究表明这种关系存在。这里重要的是,您要确定度量和目标之间关系的性质(直接/间接)以及这种关系的强度(非正式推理/经验验证)。
因此,孤立的度量不会帮助您实现目标。另一方面,对度量赋予过多意义会导致不同的误区。
仅仅为了改进度量的值而进行更改。表现为对软件进行的更改纯粹是表面功夫。可以通过确定度量值的根本原因来解决。
最常见的误区是仅仅为了改进度量的值而对系统进行更改,而不是试图实现特定的目标。此时,度量的值本身已成为目标,而不是实现更大目标的手段。这种情况导致重构仅仅是为了“取悦度量”,这是对宝贵资源的浪费。当例如一位开发人员向另一位开发人员解释说需要进行重构,因为“重复率太高了”,而不是解释说一段代码的多个副本可能会导致代码维护问题时,您就知道这种情况发生了。度量值过高或过低永远不是问题:这个值与您的目标不符才是执行重构的原因。
考虑一个项目,其中方法的参数数量与基准相比很高。当一个方法具有相对大量的参数(例如,超过 7 个)时,它可能表明该方法正在实现不同的功能。将方法拆分为较小的方法将使分别理解每个功能变得更容易。
通过此度量可能浮出水面的第二个问题是缺少相关数据对象的分组。例如,考虑一个方法,该方法将一个名为startDate的 Date 对象和另一个名为endDate的对象作为参数。名称表明这两个参数一起构成一个DatePeriod对象,其中startDate将需要在endDate之前。当多个方法将这两个参数作为输入时,引入这样一个DatePeriod对象以在模型中明确这一点可能是有益的,既可以减少未来的维护工作量,又可以减少传递给方法的参数数量。
然而,有时,参数例如被移动到周围类的字段或被映射替换,其中 (String,Object) 对表示不同的参数。虽然这两种策略都减少了方法内部的参数数量,但如果目标是提高可读性和减少未来的维护工作量,那么这些更改并没有帮助。可能是因为开发人员根本不理解目标,因此只是在处理症状。然而,在某些情况下,进行这些非目标导向的重构是为了操纵系统。在这两种情况下,重要的是让开发人员意识到潜在的目标,以确保明智地花费精力。
因此,度量永远不应按原样使用,而应将其置于上下文中,以便进行有意义的比较。此外,度量与系统的期望属性之间的关系应明确;这使您可以使用度量来安排特定的操作,这些操作将有助于实现您的目标。确保计划的操作是针对实现潜在目标的,而不仅仅是改进度量的值。
每个度量都提供了关于您的系统的特定视角。因此,组合多个度量可以对系统的当前状态进行全面的概述。使用的度量数量可能会导致两个误区。首先,考虑仅使用单个度量。
仅关注单个度量。表现为只看到显示的一个(或少数几个)度量。可以通过添加与目标相关的度量来解决。
仅使用单个软件度量来衡量您是否在实现目标的轨道上,会将该目标简化为单个维度(即,当前正在测量的度量)。然而,目标永远不是一维的。软件项目在交付期望的功能和非功能需求(如安全性、性能、可扩展性和可维护性)之间不断权衡。因此,需要多个度量来确保实现您的目标,包括指定的权衡。例如,小代码库可能更容易分析,但如果此代码库由高度复杂的代码组成,那么仍然很难进行更改。
除了提供对您的目标更全面的视图外,使用多个度量还可以帮助您找到问题的根本原因。单个度量通常只显示单个症状,而度量的组合可以帮助诊断项目中的实际问题。
例如,在一个项目中,equals和hashCode方法(用于实现 Java 中对象的相等性的方法)是系统中最长和最复杂的方法之一。此外,这些方法中发生了相对大量的重复。由于它们使用了类的所有字段,因此度量表明多个类具有相对大量的字段,这些字段也被重复了。基于这一观察,我们推断重复的字段形成了一个模型中缺少的对象。在这种情况下,我们建议研究系统的模型,以确定用新对象扩展模型是否有利。
在本例中,孤立地检查度量不会得出这个结论,但通过组合几个单元级别的度量,我们能够检测到设计缺陷。
关注过多的度量。表现为团队忽略所有度量。可以通过减少使用的度量数量来解决。
虽然使用单个度量会过度简化目标,但使用过多的度量会使实现目标变得困难(甚至不可能)。不仅难以在一大组度量中找到正确的平衡,而且当团队看到他们所做的每一项更改都导致至少一个度量下降时,士气也会受到打击。此外,当度量的值远未达到目标时,团队可能会开始认为“反正我们永远也达不到那里”,并干脆忽略这些度量。
例如,有多个项目部署了静态分析工具,但没有批判性地检查默认配置。当所讨论的工具包含例如检查标记使用制表符而不是空格时,该工具的首次运行可能会报告每个检查的大量违规(达到数十万)。在没有正确解释这个数字的情况下,很容易得出结论,在任何合理的时间内都无法达到零违规(即使可以通过简单的格式化操作轻松解决某些问题)。这种不正确的评估有时会导致团队认为该工具毫无用处并决定忽略它。
幸运的是,在其他情况下,团队会调整配置以适应特定情况,方法是限制检查的数量(例如,通过删除衡量高度相关属性、可以自动解决或与当前目标无关的检查)并实例化适当的默认值。使用这种特定配置,该工具报告的违规数量较少,可以在合理的时间内修复。
为了确保最终修复所有违规,可以扩展配置以包括其他类型的检查或更严格版本的检查。这将增加发现的违规总数,但如果做得正确,报告的违规数量不会使开发人员过于沮丧。可以重复此过程,以缓慢地将检查集扩展到所有期望的检查,而不会一次性用大量违规压垮开发人员。
软件度量对于项目经理和开发人员来说都是有用的工具。为了从度量的全部潜力中获益,请记住以下建议
• 通过将每个度量置于上下文中并定义度量与目标之间的关系,为每个度量赋予意义,并避免使度量本身成为目标。
• 使用多个度量来跟踪目标的不同维度,但避免因使用过多度量而使团队失去动力。
如果您已经在日常工作中使用了度量,请尝试将它们与特定目标联系起来。如果您目前尚未使用任何度量,但想看到它们的效果,我们建议您从小处着手:定义一个小目标(方法应该易于新员工理解);定义一小部分度量(例如,方法的长度和复杂度);定义一个目标测量值(至少 90% 的代码应该是简单的);并安装一个可以测量度量的工具。与您的同事沟通目标和度量的趋势,并体验度量的影响。
喜欢还是讨厌?请告诉我们
ERIC BOUWERS 是荷兰阿姆斯特丹 Software Improvement Group 的软件工程师和技术顾问。他是 Delft University of Technology 的兼职博士生。他对软件度量如何协助量化软件质量的架构方面感兴趣。可以通过 [email protected] 联系到他。
JOOST VISSER 是荷兰阿姆斯特丹 Software Improvement Group 的研究主管,他负责工具和服务的创新、学术关系、实习协调和一般研究。他还兼任荷兰奈梅亨 Radboud University 的大规模软件系统教授。可以通过 [email protected] 联系到他。
ARIE VAN DEURSEN 是荷兰 Delft University of Technology 的软件工程全职教授,他在那里领导软件工程研究小组。他的研究主题包括软件测试、软件架构和协作软件开发。可以通过 [email protected] 联系到他。
© 2012 1542-7730/12/0500 $10.00
最初发表于 Queue vol. 10, no. 5—
在 数字图书馆 中评论这篇文章
Mark A. Overton - IDAR 图
UML 是表示面向对象设计的实际标准。它在记录设计方面做得很好,但它有一个严重的问题:它的图表不能传达人类需要知道的内容,这使得它们难以理解。这就是为什么大多数软件开发人员仅在被迫时才使用 UML。人们根据控制层级来理解组织,例如公司。当面对人员或对象的组织时,通常第一个问题是“谁在控制这一切?” 令人惊讶的是,UML 没有一个对象控制另一个对象的概念。因此,在每种类型的 UML 图表中,似乎没有哪个对象比其邻居具有更大或更小的控制权。
Duncan Johnston-Watt - 在新管理模式下
在竞争日益激烈的全球环境中,企业面临着降低运营成本的巨大压力。与此同时,他们必须具有敏捷性,以应对动荡的市场提供的商业机会。
Derek Miers - 最佳实践 (BPM)
正如 BPM(业务流程管理)技术与传统的应用支持方法截然不同一样,BPM 开发的方法论也与传统的软件实现技术截然不同。以 CPI(持续流程改进)作为 BPM 的核心 дисциплины,推动公司工作的模型不断发展。事实上,最近的研究表明,公司至少每季度(有时甚至每年八次)微调其基于 BPM 的应用程序。关键在于,没有所谓的“完成”流程;它需要多次迭代才能产生高效的解决方案。每个工作中的基于 BPM 的流程都只是未来的起点。
James Champy - 人员和流程
当我和 Mike Hammer 在 1992 年出版《Reengineering the Corporation》时,我们理解真正的业务流程变革将对人们产生的影响。我说“真正的”流程变革,是因为管理者使用“再造工程”这个术语来描述任何和所有的公司变革计划。一位被误导的高管告诉我,他的公司不知道如何进行真正的再造工程;因此,它只是裁减了大型部门和业务部门,并期望留下的人会想办法完成他们的工作。可悲的是,这就是一些公司仍然实践流程再设计的方式:让人们工作过度和士气低落,而客户体验到糟糕的服务和低劣的质量。