量入为出(2012)

2020-09-30 02:29:50

2012年5月29日,第10卷,第5期软件度量-有用的工具还是浪费时间?对于每个珍视软件系统的这些数学抽象的开发人员来说,都有一个开发人员认为软件度量是为了让项目经理忙碌而发明的。软件度量可以是帮助您实现目标的非常强大的工具,但是正确使用它们是很重要的,因为它们还可以打击项目团队的积极性,并将开发引向错误的方向。

在过去的11年里,软件改进小组在软件度量的基础上为数百个组织提供了软件开发和风险管理方面的建议。我们在200多项调查中使用了软件度量,在这些调查中,我们检查了系统的单个快照。此外,我们还使用软件度量来跟踪400多个系统的持续开发工作。在这些项目的过程中,我们了解到在使用软件度量进行项目管理时需要避免的一些陷阱。本文将讨论其中最重要的四个方面:

·泡泡中的指标·对待指标·单轨指标·指标丰富。

了解这些陷阱将帮助您认识到它们,并有望避免它们,这将有助于您的项目取得成功。作为一名软件工程师,您对这些陷阱的了解将帮助您理解为什么项目经理想要使用软件度量,并在经理以低效的方式应用度量时帮助他们。作为一名外部顾问,在提出意见和建议时,您需要考虑陷阱。最后,如果您正在进行软件度量领域的研究,了解这些陷阱将有助于您在向实践者展示新度量时将其放在上下文中。在深入到陷阱之前,让我们看看为什么软件度量可以是有用的。

“量体裁衣,量入为出。”这句话绝对适用于软件项目团队。无论您将指标定义为什么,一旦使用它来评估团队,该指标的值就会朝着所需的值移动。因此,为了达到目标,您可以连续测量所需目标的属性,并在团队可见的位置绘制这些测量值。理想情况下,所需目标与当前测量值一起绘制,以指示到目标的距离。

设想一个项目,其中特定用例的运行时性能至关重要。在这种情况下,它有助于创建一个测试,在该测试中每天测量用例的执行时间。通过绘制每日数据点与期望值的关系图,并确保团队看到此度量,每个人都可以清楚地知道是否实现了目标,或者最近的开发行动是否正在带领团队远离目标。

尽管这看起来很简单,但这项技术可能会以许多微妙的方式不正确地应用。例如,想象一下这样一种情况,客户因为报告产品中没有及时解决的问题而感到不高兴。为了提高客户满意度,项目团队跟踪发布中问题的平均解决时间,原因是平均解决时间越短,客户满意度越高。

不幸的是,现实并非如此简单。首先,更快地解决问题可能会导致不想要的副作用-例如,现在快速修复可能会导致更长的修复时间,因为发生了技术债务。其次,如果这些修复程序一年只发布一次,则在几天内解决问题对客户没有任何帮助。最后,当根本不需要修复时,客户无疑会更满意-也就是说,问题从一开始就不会出现在产品中。

因此,使用指标允许您朝着一个目标前进,该目标可以是高级业务主张(“该系统的维护成本每年不应超过100,000美元”),也可以是更面向技术的(“所有页面应在10秒内加载”)。不幸的是,根据遇到的陷阱,使用度量也会阻止您达到期望的目标。在本文的其余部分中,我们将讨论我们经常遇到的一些陷阱,并解释如何识别和避免它们。

软件度量可以在软件系统的不同视图上度量。本文重点介绍在系统代码库的特定版本上计算的指标,但缺陷也适用于在其他视图上计算的指标。

假设代码库只包含当前项目的代码,软件产品度量将建立一个基本事实。然而,仅计算指标是不够的。还需要两个操作来解释度量值:添加上下文;以及建立与目标的关系。

为了说明这些点,我们使用LOC(代码行)度量来提供有关项目当前规模的详细信息。尽管对一行代码的构成有多种定义,但这样的度量可以用来推断所检查的代码库是否完整,或者是否包含无关的代码,例如复制库。然而,要做到这一点,度量应该放在上下文中,这将我们带入第一个陷阱。

在没有正确解释的情况下使用度量。由于不能解释给定度量的值意味着什么而被认可。可以通过将度量置于与目标相关的上下文中来解决。

度量的单个数据点的有用性是有限的。知道一个系统是100,000个LOC本身是没有意义的,因为这个数字本身并不能解释系统是大是小。例如,为了有用,度量的值应该与取自项目历史或其他项目基准的数据点进行比较。在第一个场景中,您可以发现应该由外部事件解释的趋势。例如,图1中的图表显示了一个软件系统从2010年1月到2011年7月的LOC。

这里想到的第一个问题是:“为什么系统规模在2010年7月下降了这么多?”如果这个问题的答案是“我们删除了前面复制的大量开放源代码”,那么就没有问题(除了首先包含此代码之外)。如果答案是“我们意外地删除了部分代码库”,那么引入一种不同的源代码版本管理方法可能是明智的。在本例中,答案是计划了一个操作来大幅减少所需的配置量;考虑到删除的代码量,该操作显然是成功的。

请注意,将度量放在上下文中的好处之一是,它允许您将重点放在图表的重要部分。关于在某个时间点发生了什么或者为什么该值明显偏离其他系统的问题变得比关于如何度量该度量的具体细节更重要。通常,无论是有意还是无意,人们都试图将讨论引向“这个度量是如何衡量的?”而不是“这些数据点告诉我什么?”在大多数情况下,度量的准确构造对于从数据中得出的结论并不重要。例如,考虑图2和图3中显示的三个曲线图,它们表示计算系统体积的不同方式。图2显示的代码行计为至少包含一个非注释或空格的字符(橙色)的每一行,以及计为所有换行字符的代码行(蓝色)。图3显示了使用的文件数。

趋势线表明,尽管规模不同,但这些成交量指标都显示了相同的事件。这意味着,这些指标中的每一个都是比较系统与其他系统的容量的很好候选指标。只要用同样的方法测量其他系统的体积,从数据中得出的结论就会非常相似。

不同的趋势线提出了第二个问题:“为什么在经历了一段时间的成交量增加之后,成交量会减少?”答案可以通过对这一特定系统进行更改的正常方式找到。当系统的容量增加时,会安排一个动作来确定是否可以进行新的抽象,这通常就是这种情况。这种类型的重构可以显著减小代码库的大小,从而降低维护工作量,并使向系统添加功能变得更容易。因此,这里的目标是通过(以及其他方式)保持相对较小的代码库来减少维护工作。

在理想情况下,在期望目标(例如,减少的维护工作量)和度量(例如,小代码库)之间存在直接关系。在某些情况下,这种关系是基于非正式推理的(例如,当系统的代码库很小时,更容易分析系统做什么);在其他情况下,科学研究表明这种关系是存在的。这里重要的是,您既要确定度量和目标之间关系的性质(直接/间接),也要确定这种关系的强度(非正式推理/经验验证)。

因此,孤立的指标不会帮助您实现目标。另一方面,为指标赋予过多的含义会导致不同的陷阱。

仅仅为了提高度量值而进行更改。当对软件所做的更改纯粹是表面上的更改时被识别。可以通过确定度量值的根本原因来解决。

最常见的陷阱是仅仅为了提高指标的价值而对系统进行更改,而不是试图达到特定的目标。在这一点上,指标的价值本身就变成了一个目标,而不是实现更大目标的一种手段。这种情况导致了简单地“取悦度量”的重构,这是对宝贵资源的浪费。例如,当一名开发人员向另一名开发人员解释说需要进行重构是因为“重复百分比太高”,而不是解释一段代码的多个副本会在维护代码时造成问题时,就会发生这种情况。度量值过高或过低从来都不是问题:该值与您的目标不符的事实应该是执行重构的原因。

考虑一个项目,在该项目中,与基准相比,方法的参数数量较多。当方法具有相对较大数量的参数(例如,多于7个)时,可以指示该方法正在实现不同的功能。将方法拆分成较小的方法将使单独理解每个功能变得更容易。

通过该指标可能出现的第二个问题是缺少相关数据对象的分组。例如,考虑一个将名为startDate的Date对象和另一个名为endDate的Date对象作为参数的方法。名称表明这两个参数共同构成了一个DatePeriod对象,其中startDate需要在endDate之前。当多个方法将这两个参数作为输入时,在模型中引入这样一个DatePeriod对象来明确这一点可能是有益的,可以减少将来的维护工作量和传递给方法的参数数量。

但是,有时,例如,参数会被移到周围类的字段中,或者替换为映射,在映射中,(字符串、对象)对表示不同的参数。虽然这两种策略都减少了方法内部的参数数量,但如果目标是提高可读性并减少未来的维护工作,那么这些更改无济于事。进行这种类型的重构可能是因为开发人员根本不了解目标,因此正在治疗症状。然而,也有一些情况下,这些非面向目标的重构是为了玩弄系统。在这两种情况下,重要的是让开发人员意识到基本目标,以确保明智地使用这些努力。

因此,永远不应该按原样使用度量,而应该将其放在能够进行有意义的比较的上下文中。此外,指标和系统所需属性之间的关系应该清晰;这使您能够使用指标来计划有助于实现目标的特定操作。确保计划的操作的目标是实现基本目标,而不是只提高指标的值。

每个指标都提供了有关您系统的特定观点。因此,组合多个指标可以平衡地概述系统的当前状态。使用的指标数量可能会导致两个陷阱。首先,考虑只使用单个度量。

只关注一个指标。通过只看到显示的一个度量(几个度量中的一个)来识别的。可以通过添加与目标相关的指标来解决。

仅使用单一软件度量来衡量您是否在实现目标的轨道上,将该目标减少到单一维度(即,当前正在度量的度量)。然而,目标从来都不是单向度的。软件项目在交付所需功能和非功能需求(如安全性、性能、可伸缩性和可维护性)之间需要不断权衡。因此,多个指标是必要的,以确保达到您的目标,包括指定的权衡。例如,较小的代码库可能更容易分析,但如果此代码库由高度复杂的代码组成,则仍然很难进行更改。

除了为您的目标提供更平衡的视图之外,使用多个指标还可以帮助您找到问题的根本原因。单个指标通常只显示一个症状,而多个指标的组合可以帮助诊断项目中的实际疾病。

例如,在一个项目中,equals和hashCode方法(用于在Java中实现对象的等价性)是系统中最长和最复杂的方法之一。此外,在这些方法中出现的重复百分比相对较大。因为它们使用类的所有字段,所以度量指示多个类具有相对大量的字段,这些字段也是重复的。基于这一观察,我们推断重复的字段形成了模型中缺失的对象。在这种情况下,我们建议查看系统的模型,以确定使用新对象扩展模型是否有益。

在本例中,单独检查指标不会得出此结论,但是通过组合几个单元级别的指标,我们能够检测到设计缺陷。

专注于太多的指标。当团队忽略所有指标时识别。可以通过减少使用的指标数量来解决。

虽然使用单一指标会过度简化目标,但使用太多指标会使您很难(甚至不可能)实现目标。不仅很难在一大组指标之间找到正确的平衡,而且当团队看到他们所做的每一项更改都会导致至少一个指标的下降时,这对士气是不利的。此外,当指标的值远离目标时,团队可能会开始思考,“反正我们永远也达不到目标”,而干脆忽略这些指标。

例如,已经有多个项目在没有严格检查默认配置的情况下部署了静态分析工具。例如,当所讨论的工具包含标记使用制表符而不是空格的检查时,该工具的第一次运行可能会报告每个检查的大量违规(达到数十万)。如果不正确解释这个数字,很容易得出结论:在任何合理的时间内都不可能达到零违规(即使一些问题可以通过简单的格式化操作轻松解决)。这种不正确的评估有时会导致团队认为该工具毫无用处,并决定忽略它。

幸运的是,在其他情况下,团队通过限制检查的数量(例如,通过删除测量高度相关的、可以自动解决的或与当前目标无关的检查)和实例化适当的默认值来调整配置以适应特定情况。使用这样的特定配置,该工具报告的违规数量较少,可以在合理的时间内修复。

要确保最终修复所有违规,可以扩展配置以包括其他类型的检查或更严格版本的检查。这将增加发现的违规总数,但是当正确处理时,报告的违规数量并不会使开发人员失去太多积极性。可以重复此过程,以缓慢地将检查集扩展到所有所需的检查,而不会立即用大量违规使开发人员不堪重负。

软件度量对于项目经理和开发人员都是有用的工具。要从指标的全部潜力中获益,请牢记以下建议:

·通过将每个指标放在上下文中并定义指标与您的目标之间的关系来赋予其意义,并避免使指标本身成为目标。

·使用多个指标来跟踪目标的不同维度,但避免使用过多的指标打击团队的积极性。

如果您已经在日常工作中使用度量标准,请尝试将它们与特定目标联系起来。如果您目前没有使用任何指标,但希望看到其效果,我们建议您从小处开始:定义一个小目标(方法对于新人员来说应该简单易懂);定义一组小的指标(例如,方法的长度和复杂性);定义一个目标度量(至少90%的代码应该是简单的);并安装一个可以度量该度量的工具。向您的同事传达指标的目标和趋势,并体验指标的影响。

Eric BOUWERS是荷兰阿姆斯特丹软件改进小组的软件工程师和技术顾问。他是代尔夫特理工大学的兼职博士生。他感兴趣的是软件度量如何帮助量化软件质量的体系结构方面。可以通过[受保护的电子邮件]联系到他。

Joost Visser是荷兰阿姆斯特丹软件改进小组的研究主管,负责工具和服务的创新、学术关系、实习协调和一般研究。他还兼职担任荷兰奈梅亨拉德布大学(Radboud University Nijmegen)的大型软件系统教授。可以通过[受保护的电子邮件]联系到他。

Arie van Deursen是荷兰代尔夫特理工大学软件工程的全职教授,在那里他领导着软件工程研究小组。他的研究主题包括软件测试、软件架构和协作软件开发。可以通过[受保护的电子邮件]联系到他。

最初发表在队列VOL中。10,编号5-在ACM数字图书馆中查看此项目。

相关:Mark A.Overton-IDAR Graph UML是表示面向对象设计的事实标准。它在记录设计方面做得很好,但它有一个严重的问题:它的图表没有传达人类需要知道的东西,使得它们很难理解。这就是为什么大多数软件开发人员只有在被迫使用UML时才使用UML。人们从控制层次结构的角度来理解一个组织,如公司。当面对人员或对象的组织时,第一个问题通常是,是什么在控制这一切?令人惊讶的是,UML没有一个对象控制另一个对象的概念。因此,在每种类型的UML图中,没有一个对象看起来具有更大的或。

.