65.9K
CodeProject 正在变化。 阅读更多。
Home

软件估算示例

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (13投票s)

2013年12月26日

CPOL

19分钟阅读

viewsIcon

102188

估算软件产品的规模、工作量和进度

引言

“你或你的团队什么时候能完成这个项目、软件或功能?”你多久会从你的老板、项目负责人或经理那里听到这句话?我经常听到,对我来说,仅凭判断或没有任何准备就给出一个估算总是一件烦人的事。我总是试图在书中寻找答案,但估算是一个很难理解的课题。估算既是一门科学,也是一门艺术。

估算是一个庞大的课题,但在这篇文章中,我只涉及估算中一些最重要的方面。本文是为那些刚开始踏入估算世界的人准备的。本文也是为那些希望根据科学和经过验证的估算原则,而不仅仅是凭个人判断,来回答老板关于他们将要开发的项目估算问题的人准备的。

通过阅读本文,读者将能够估算未来项目的规模、工作量和进度。本文的第二个目标是使读者能够建立自己组织/团队的项目度量体系。在本文中,我首先讨论了在估算过程中可能面临的挑战或问题,然后是估算的目的和一些关于估算的误解。之后,我将讨论估算的好处,然后讨论估算的构成要素。接着,我将简要讨论可用于估算的各种技术。接下来,我将讨论我的估算经验,并带您回顾我过去两个项目的估算过程。最后,我将讨论度量和历史数据。

估算中的挑战

在估算任何软件项目时,我们常常忽略了许多可能影响整体估算的因素。因此,在给出估算之前,应该考虑这些因素。

人员经验 

参与项目的人员会影响估算。经验丰富的开发人员通常比初级开发人员表现得更好。因此,在估算时,了解在项目执行期间实际工作或执行任务的人员非常重要。

项目规模和项目类型 

项目规模也会影响估算过程。我们不能简单地用过去小型项目的经验来估算大型项目。研究表明,工作量并非线性增长,而是指数级增长。这是因为大型项目需要在组件之间进行更多的集成工作。在大型项目中,我们需要更大的团队,而团队的规模也会影响总工作量,因为在大型团队中,我们必须处理团队成员之间的沟通问题。因此,在大型团队中,会增加诸如沟通和协调等新的工作,这会增加完成项目所需的总工作量。

项目类型是另一个重要因素。如果一个组织有开发桌面应用的经验,他们完成一个Web应用可能需要更多时间。因此,当你建立度量或历史数据并进行估算时,务必要考虑到项目类型。

不确定性水平 

在每个项目中,开发过程都有许多阶段或步骤。这些阶段从初始构想到最终产品输出,可能包括初始构想、需求、设计、开发、测试,然后交付到生产环境。在项目初期,关于最终产品或最终成果存在很大的不确定性。因为需求可能在开发的任何阶段发生变化,或者新的参数或问题可能在任何阶段出现。由于这种现象,在估算过程中,如果你在项目开始时对项目进行估算,那么与在后期或最终阶段的估算相比,这个估算的准确性会较低。

随着项目从初始构想阶段进展到实施阶段,不确定性水平会降低。如果在开发的后期阶段重新估算项目,可以得到比初始估算更准确的结果。

不同的假设 

另一个需要考虑的因素是所使用的编程语言,因为一些编程语言支持庞大的生态系统。对于某些编程语言,有许多可用的工具,而其他语言则没有。如果你选择一个有大型社区支持的编程语言,你将拥有更多的可用工具和更容易获得的帮助。这种社区支持可以极大地提高开发团队的生产力。

同样,在估算项目时,必须考虑到开发人员的可用时间。在估算一个项目时,我们必须考虑开发人员是全职投入,还是在开发期间还会参与其他项目。

估算的目的和方法

在两种情况下需要对项目进行估算。第一种情况是,你的老板来找你,给你一个功能列表或需求列表。然后,要求你给出实现所有这些功能所需的总时间。你估算项目并向老板汇报。老板将这些估算作为一个大型项目的大额分项。在这种情况下,当你进行估算时,没有时间限制。在这种估算中,你不会受到截止日期的压力。这种情况很少发生。

在第二种情况下,你有一个截止日期和一份要实现的功能列表。你的任务是为所有能在截止日期前完成的功能制定一个估算。我们大多数时候面临的是这第二种情况。有时候,即使动用所有可用资源,也无法在截止日期或之前交付成果。在这种情况下,人们必须协商调整截止日期或要实现的功能数量。

仅靠估算并不能保证项目在承诺的日期完成。还需要项目控制和良好的项目管理技能,才能根据估算完成项目。因此,在软件项目管理中,估算只是其中的一部分,仅有助于规划。

估算的好处

有了估算,你就有了控制项目的框架。你可以在项目期间的任何时候衡量自己的表现。估算有助于更好地分配资源。估算为制定计划提供了基本的基础。好的估算为更好的风险管理和高项目进展可见性提供了基础。

我们在估算中做什么?

当接到估算任务时,需要估算三件事:规模、工作量和进度。可以采用一种或多种技术来计算这些估算值。在估算时,最好采用多种技术。这将帮助你对估算进行合理性检查。因为如果两种技术给出的估算值相差甚远,那就意味着你进行估算的某些假设是错误的。

在估算中,我们首先估算规模。这是因为大多数工作量或进度的计算公式都需要提供规模参数。规模可以用LOC(代码行数)或功能点来表示。这是计算软件规模的两个主要单位。由于在项目开始时无法得到LOC,因此使用功能点计算。通过功能点,我们可以估算实现这些功能点所需的LOC。功能点到LOC的转换计算取决于你使用的编程语言。例如,在C#中实现一个功能点需要40到80行代码,中位值为55行。还有其他用于计算规模估算的单位,例如:用户故事数、用例数和网页数。

工作量是直接根据软件规模计算出来的。有很多模型可以用来计算工作量。工作量是一个人完成项目所需的时间。工作量可以用人月、人周或人时来计算。这里的周和月取决于公司的政策。例如,在我的组织中,每周有32个工作小时。如果团队中不止一个人,你也必须考虑到这一点,因为它肯定会缩短进度。

估算之后,就可以制定完成项目的进度计划。也有模型和技术用于估算软件项目的进度。进度以月或周为单位计算。在进行进度估算时,有一个要点。有人可能会问,通过增加越来越多的资源,我们可以将进度压缩多少。但在软件项目估算中,进度不能无限压缩。举个例子,如果4个人需要4个月完成一个项目,那么40个人就需要1个月完成该项目,照此推算,800个人可以在一天内完成项目!这是不可能的。因此,进度压缩不能超过某个点。那个点及其之后被称为“不可能区域”。根据一项研究,进度不能压缩超过其正常进度的25%。这个进度压缩限制的原因是,为了缩短进度,必须增加开发人员的数量,而这会增加团队成员之间的沟通问题。另一个原因是,在更短的时间内,必须并行完成任务,如果这些任务相互依赖,那么依赖任务中产生的错误将会传播。

 

现在,让我们讨论估算的过程或流程。为了简单起见,估算的流程是:

规模 ---> 工作量 ---> 进度 

首先估算规模,根据规模可以估算工作量,然后根据工作量可以轻松计算出进度。读者将在接下来的示例中看到这个过程的应用。

有哪些不同类型的技术?

估算技术有两大类。第一类技术基于科学方法,如COCOMO。在科学方法中,我们有数学方程,通过这些方程可以计算出工作量和进度。第二类基于经验方法。例如专家判断和与过去项目的非正式比较。基于软件的工具使用科学方法,并利用历史数据来校准这些科学方法。

一些技术适用于顺序开发模型,而另一些估算技术适用于迭代开发模型。同样,一些技术适用于项目初期使用,而另一些则在项目后期使用。一些技术还取决于项目的规模,大型项目、中型项目和小型项目适用不同的技术。由于对这些技术的描述超出了本文的范围,因此留给读者自行探索。

两个项目的估算示例

为了更好地理解估算过程和一些估算概念,我以我之前的两个项目为例。这些项目的一个好处是,我都为每个项目保留了日志。例如,每个项目我都有一个这样的日志文件:

日期,项目投入时间,项目相关任务描述

例如:4月30日,2小时,为项目A(项目名称)实现文件解析

我将所有这些日志记录在我的个人日志中。

借助这个日志,我可以轻松计算出完成项目的总时间。

我以两个项目为例,根据它们的功能描述计算完成项目所需的总功能点。我使用功能点是因为从功能列表和需求文档中推导出功能点比较容易。根据这些功能点,我计算出使用C#实现这些功能点所需的预期代码行数。之后,我将其与完成项目的实际代码行数进行比较。

通过这种方式,我估算了规模,然后将其与实际的SLOC(源代码行数)进行比较。我发现了非常惊人的相似之处。通过这种方式,我估算了工作量和进度,然后将其与完成项目的实际工作量和进度进行比较。这项研究让我对估算技术有了很多认识。

因此,我在这里分享我每个项目的经验。为了保护组织数据,我不能透露项目的真实名称,因此我使用了另外两个名字:项目A和项目B。

(1)项目A的估算 

现在我将根据项目A的需求或功能列表来估算规模、工作量和进度。之后,我将把这个估算与实际的规模、工作量和进度进行比较。通过这种方式,我将向读者展示估算是如何进行的,以及在项目完成后如何进行比较。

项目A的规模

如前所述,我使用功能点来估算规模。简而言之,项目A是一个数据采集和处理软件。它在屏幕上显示采集到的数据。

在功能点估算中,我们必须考虑所有的外部输入、外部输出、内部逻辑文件、外部接口文件和外部查询。现在对于项目A:

外部输入 复杂度
数据流
配置文件
用户选择
用户输入

如您所见,每个参数都被赋予了一个复杂度值,即高、低或中。可以通过确定编写该特定参数代码时将要处理的复杂度来给出这个值。同样,我们估算外部输出:

外部输出 复杂度
遥测数据1屏幕媒体
遥测时序屏幕低功耗
遥测数据2屏幕媒体
状态屏幕
 

现在是内部逻辑文件

内部逻辑文件 复杂度
存储文件媒体
中间缓冲区
中间结果
通道文件

现在是外部接口文件

外部接口文件 复杂度
数据2的外部接口

 

外部查询 

无。

 

现在您可以看到,所有这些文件和输入的评级只有在您仔细分析了规格或需求后才可能实现。如果遗漏了任何重要参数,都将导致估算错误。因此,由经验丰富的开发人员进行的功能点估算更为准确。

在确定所有可能的参数之后,可以如下计算功能点:

参数  
外部输入2*3=61*4=41*6=6
外部输出1*4=43*5=150*7=0
外部查询0*3=0 0*4=00*6=0
内部逻辑文件2*7=141*10=101*15=15 
外部接口文件1*5=50*7=00*10=0 

这里乘法中的第一个数字(粗体)是该类别中的参数计数,第二个数字是功能点方法本身给出的一个固定数字。

如果我们将每一项的结果相加,得到的值是79。这被称为未调整的功能点(FP)值。我们可以将这个未调整的功能点值作为规模,或者使用一个乘数来调整它。这个乘数可以来自过去的项目,即历史数据,或者来自你正在估算的项目类型。我将尝试使用下面显示的3个乘数:

乘数调整后功能点 
179
1.2 94.8 
0.863.2
 

现在可以选择任何一个乘数,然后将其与未调整的功能点相乘。这将得到调整后的功能点计数。

有一个表格可以将功能点计算转换为源代码行数(SLOC)度量。实现每个功能点需要40到80行C#代码,中位值为55。

 

调整后功能点C# LOC 中位数 C# LOC 范围 
7943453160 至 6320
94.852143792 至 7584
63.234762523 至 5056

因此,通过这种方式,我估算了项目A的规模。现在让我们用现实来检验一下。这些数字与现实接近吗?由于我有项目A软件的实际代码,我可以计算软件的实际代码行数。

我使用了一个工具来计算LOC。我没有计算空白行和设计器生成的代码,但我计算了注释,因为在编写好的注释上投入了大量精力。因此,在实际代码中,我得到了4700行代码,这与估算的4345行非常接近。可以看出,这个估算与实际编写的代码行数非常接近。

因此,我认为我用于调整功能点的乘数为1,并将其记录在我的历史数据中。

项目A的工作量

对于工作量估算,我使用了ISBSG(国际软件基准标准组织)的方法。ISBSG以功能点为输入,并结合完成项目所需的人员数量,返回工作量估算。由于我已经估算了项目A的规模,并且只有一个人在做这项工作,因此我可以估算出完成项目A所需的工作量。

ISBSG(使用桌面软件方程式)

ISBSG  Effort  = 0.157 * functionPoints ^ 0.591 * MaximumTeamSize ^ 0.810
ISBSG Effort   = 0.157 * 79 ^ 0.591 * 1^0.810 
       = 2.07 staff-month  

实际上,从我的日志记录中,我可以计算出实际工作量为

Actual effort = 2.2045 staff-month  = 291 men-hours (132 hours in one staff months)  

因此,可以看出估算中只有6%的误差。

项目A的进度

可以使用基本进度方程计算

Schedule Equation In months = 3.0 * Staff-Months ^ (1/3)
    = 3.0 * 2.2045 ^ (1/3)(Using the actual-effort for Project A)
    = 3.9 Months.   
这个3.0可以是2.0或4.0,具体取决于你组织的历史数据,但如果你没有历史数据,你可以使用3.0这个数字。
这个进度方程主要适用于中到大型项目以及顺序执行的项目。
实际工作量或项目完成的实际月数为3个月,这与进度方程的输出大致相等。
估算进度的其他方法是与你所在组织内在该领域已完成的过去项目进行比较。与过去项目比较比任何其他方法都能得出更准确的估算。
使用估算软件会给我们更准确的结果,但估算软件通常需要校准数据或你自己组织的过去项目数据。

(2)项目B的估算 

现在,与项目A类似,我对项目B执行了相同的程序,估算了规模、工作量和进度,然后将每一个估算值与实际的规模、工作量和进度进行了比较。我将在这里详细介绍所有步骤。

项目B的规模

外部输入复杂性
串口数据
屏幕控制
现场测试数据文件
瓦片
用户移动控制
仿真输入文件
 

外部输出 复杂性
1) 屏幕显示
2) 屏幕状态
 

内部逻辑文件 复杂度
1) 瓦片文件
2) Excel结果

 

外部接口文件 复杂度 
1) 瓦片下载

外部查询 

现在在下表中估算未调整的功能点:

参数  
外部输入1*3=3 3*4=122*6=12
外部输出1*4=41*7=7
外部查询
内部逻辑文件1*7=7 1*15=15
外部接口文件0

1*10=10  

这里未调整的功能点计数是66。

用于调整

乘数调整后功能点
166
0.852.8
1.279.2

 

调整后功能点C# LOC 中位数C# LOC 范围
6636302640 至 5280
52.829042112 至 4224
79.24354 

3168 至 7128

现在我们已经估算了规模。

项目B的实际大小为:2761 LOC。没有计算自动生成的代码和空行。

当我们看乘数时,乘数“1”有30%的误差,而“0.8”的乘数有5%的误差。

这里,乘数0.8产生的功能点和代码行数(LOC)与实际值非常接近。因此,我在我的历史数据中记录了这类项目。为简单起见,读者可以选择任何一个乘数并坚持使用它。

项目B的工作量

ISBSG Effort = 0.157 * 52.8 ^ 0.591 * 1^0.810               taking 52.8 as total function points
= 1.6367 (staff months)  

现在,根据我的日志记录,完成该项目的实际工作量是:

Actual-Effort = 1.522 staff-month
   = 201 men-hours (Considering 132 hours/staff month)  

可以看出,原始估算存在2.5%的误差。

项目B的进度

使用基本进度方程估算进度

Estimated Schedule in Months = 3.0 * Staff-Months ^ (1/3)
    = 3.0* 1.522 ^ (1/3)(using actual effort)
    = 3.45 Months 

根据我的日志记录,完成该项目的实际进度或时间约为3个月

 

历史数据及其重要性

我的假设

在深入研究估算世界之前,我假设历史数据或行业特定数据必须包含超过100个项目。但在估算中情况并非如此。你只需要2到3个项目的数据。这些数据量足以估算未来的项目。这些数据量足以用于任何类型的校准软件,并校准任何其他估算技术,如COCOMO。因此,我鼓励本文的读者去收集他们组织的数据,即使他们到目前为止只完成了两个项目。

行业特定数据和组织数据之间存在差异。行业特定数据是从从事同类型项目的组织中收集的。这种行业特定数据不是很准确,因为每个组织都有其自身的环境,这会影响整体估算。组织数据或历史数据与单个组织或您当前工作的组织有关。历史数据非常重要,可用于获得准确的估算。

我如何建立我的历史数据?

在理解了历史数据并澄清了假设的困惑之后,我尝试收集我过去项目的信息。虽然我过去完成了很多项目,但我没有它们的记录或日志。但我确实有最近两个项目的记录或日志。

为了拥有一些历史数据,需要收集什么?从过去的项目中,可以收集每个项目的规模、工作量和进度。2到3个项目的数据就足以进行准确的估算。

在我的组织中,我有以下参数:

1天 = 6人时

1周 = 30人时

1个月 = 132人时

1个月 = 22天

您可以根据自己的组织调整这些参数。

以下是我收集的用于未来项目估算的历史数据。这些数据与我之前在本文中讨论的两个例子有关。

历史数据矩阵:

项目名称 规模(LOC)  规模(FPS) 工作量(小时)LOC/小时FP/小时进度
项目A50007929117.180.2713个月
项目B276152.8201 13.73630.262 3个月

这份历史数据基于我在本文上面讨论的两个例子。

在估算软件中的应用

您可以从南加州大学(USC)网站的这个链接找到一个非常好的基于COCOMO的估算软件。另一个软件来自Construx,可以免费使用,并可从这里下载。在这两个软件工具中,您都可以使用历史数据进行校准,以获得准确的估算。

如果提供了校准数据(也称为历史数据),这两款软件在估算工作量和进度方面都非常出色。可以试试这些估算软件,看看它们能如何帮助你。

生产力矩阵

从历史数据中,可以衡量组织的生产力。从以上两个例子中,我可以得出这里的生产力矩阵。

以人天为单位的生产力矩阵 

项目名称 LOC 帧率 (FPS) 
项目A103.081.626
项目B82.41781.572

通过使用这些矩阵,我可以估算未来任何要求我开发的项目。

最后,我强调每个人都应该收集自己的历史数据。在完成两个项目后,他们就可以使用像COCOMO这样的现代技术和基于软件的技术来估算他们未来的项目。

结论 

在本文中,我简要介绍了估算这一主题,以及我们在估算过程中面临的挑战。我通过两个项目的例子描述了估算过程,并分享了一些我自己的经验。我还描述了管理历史数据的重要性,并为管理历史数据提供了指导和示例。读者可以立即利用本文中给出的信息开始估算他们未来的项目。他们最初的估算可能存在错误,但在完成几个项目后,他们的技能会得到提升。毕竟,估算既是一门科学,也是一门艺术。

 额外资源

1) 书籍,《软件工程:实践者的研究方法》作者:Roger S Pressman

2) 书籍,《软件估算:揭开神秘的黑盒艺术》作者:Steve McConnell


© . All rights reserved.