作者:张克强
软件项目工作量估算从估算依据上看可以分成如下两类:
1,基于规模估算
2,基于工作量估算
基于规模估算的情况下,需要估算软件项目的规模。本文首先来看规模方面的问题。
问题1:如何表达规模?
软件产品或项目的功能规模是涉及软件开发和交易的成本、项目资源投入的预测、项目维护成本的预算、项目质量管理的要求以及产品上市的时间等方面的关键指标。因此,进行软件产品的功能规模测量显得尤其重要。
如何测量软件规模这个问题自软件工程诞生起就一直是这个领域的焦点问题。刚开始,人们很自然的使用代码行数作为规模的表达。但是作为规模表达方式的代码行数随着时间和技术的发展,越来越不正确了,主要原因是1,新工具自动生成大量代码行;2复用构件或源代码;3,难以区分新开发代码和旧代码。而且最重要的是源代码行数的实际测量只能在软件项目开发的后期,缺乏在前期较精确指导项目的能力。
世界上各个组织都看到了代码行作为规模表达方式的弊端,纷纷发展了各自的规模表达方式,其中IFPUG的功能点计数是其中有显著影响的。但是由于规模度量存在各种各样的情况,IFPUG的方法并没有统治地位,涌现了多种规模度量方法。目前,国内外软件领域的专家对软件功能规模测量开展了极富成效的研究,提出了各类工业标准。国际标准化组织(ISO)和国际电工委员会(IEC)联合技术委员会分别于1998、2002和2003年推出了软件功能规模测量方面的系列标准。国际标准化组织ISO/IEC相继发表了4个功能规模测量方法的标准,它们是:
——ISO/IEC 19761(COSMIC-FFP方法);
——ISO/IEC 20926(IFPUG方法);
——ISO/IEC 20968(MkⅡ方法);
——ISO/IEC 24750(NESMA方法)。
其中,COSMIC-FFP方法声明可以应用于管理信息系统(MIS)和实时类型二类软件,IFPUG方法声明可用于所有类型的软件,MkⅡ方法声明可用于逻辑事务能被确定的任何软件类型,NESMA方法非常类似于IFPUG方法也可以用于所有软件类型。
我国也十分重视这类标准的研究,于2001年开始了这方面的工作。
我国相继发布了GB/T 18491.1~6《信息技术 软件测量 功能规模测量》的系列标准,但具体的测量方法不包含在该系列标准中。由中国工业和信息化部支持的《软件工程 软件功能规模测量方法 功能点计数》(征求意见稿)于2011年9月1日完成,现在正处于意见征集阶段,这个标准非等效采用了ISO/IEC 20926:2003,为所有类型的软件开发的全生存周期提供了一种统一的软件功能规模计数方法。
除了以上方法,常见的方法还有:
其它各类功能点方法
代码行数 LOC
数据点
对象点
用例点
故事点,故事点是比较特殊的一个方法,下文还有说明。
不少公司发展了自己的功能规模测量方法。
问题2:如何测量规模?
以上这些规模测量方法的基本框架是相同的,下面是一个概要的介绍。
首先对做所测量对象进行分解,针对分解得到的各个部分,估算或测量模块的初始规模u(有些场合称为未调整功能点),乘以模块级调节参数f1,得到模块一次调整后的规模,将所有一次调整后的规模累加得到一次调整后的总规模,乘以总体调节系数f2,得到二次调整后的总规模s,见如下公式:
总规模S = (西格玛u*f1)*f2
有些方法只有一次调整,有些方法有上述的2次调整。
问题3:如何根据规模估算工作量
经过前人的大量研究,认为规模与工作量的数学关系如以下公式所示:
估算工作量e = a * S的b次方 + c
s是代表了规模, a,b,c是参数,其值的获得需要大量数据分析,一般采用非线性转换到线性,再进行线性回归分析。b的取值一般是1到1.2之间。
从以上公式可以看出,随着规模s的增加,工作量e是指数级增长,表明了软件项目规模越大,所需要的工作量增加得更多,表明了软件开发规模不经济的情况,这和我们直观的感受是一致的。
世界上各个软件生产率研究组织(比如ISBSG,SPR,日本的IPA SEC等)收集了成千上万个项目数据,开展各种各样的数学分析,试图得到在各种情况下 a, b ,c 的取值。
在第5届世界软件质量大会上,来自Toyo University的野中诚(Makoto Nonaka)介绍了日本IPA SEC组织(http://sec.ipa.go.jp/),举了某种情况下的一个工作量估算公式:
工数 = e的0.542次方*FP的1.154次方 = 1.719*FP的1.154次方。
对于一般的场合,其规模在一定有限的范围之内,那么可以假设工作量与规模的关系是简单的线性正相关,那么上述公式就变为:
估算工作量e = a * S,即b=1, c=0 。 那么参数 a 就是 表明了生产率,a的单位是 工作量/单位规模,比如8工时/FP;另外一种生产率单位是规模/单位工作量,比如30FP/Man-month,如果采用常见的生产率单位,那么a就是生产率的倒数。
这种做法是更容易为各方所理解,在很多组织里常见到这个做法。
对比基于规模的工作量估算,直接的工作量估算方法所积累的数据和资料就少了,没有看到哪个组织在收集积累这类数据,这与直接工作量估算方法本身的特征也有关系。
下面来看看直接工作量估算方面的问题。
问题4,如何表达工作量?
工作量的单位一般是工时、人天、人月、人年。这些不同的单位是可以换算的。不同单位换算并不麻烦,在同一个国家没有差异,在不同国家因为法定假期的不同,1人月所对应的人天可能是不同的,但差异并不大。真正麻烦的是工作量表达有如下两种:
1,工作量
2,理想工作量
而工作量也有差异,有些地方是计毛时,比如一天都在某项目上工作,就直接记为8工时,有些地方是计净时,虽然一天都在某项目上工作,但会把诸如非直接相关的工作(如部门例会、参加其它项目评审)等等剥离,一天在某项目上的工作量只有5工时。 这样看,可以发现计净时的工作量与理想工作量比较接近,但注意并不完全相等。
问题5,如何直接估算工作量?
主要的思路是分解和类比。
把待完成物细分,根据以往估算和经验进行类比估算。 对于以往估算和经验的处理,可以分为两种做法:
1,不做特别处理,自然停留在团队成员的头脑里,使用时并不明确要求、不保证能够想起来对照
2,记录典型事物(特性,用户故事等)所需要的工作量,得到一套基准类比库,新任务根据这个基准类比库来估算。
在使用理想工作量的情况下,需要一个名为capacity的参数。工作量 = 理想工作量 / capacity ,capacity的取值一般是50% ~ 80%。
在估算时,本次待完成的理想工作量 = 计划的工作容量 * capacity
在回顾时,capacity = 原估算的理想工作量 / 实际工作容量 * 100%,注意工作容量并不等于工作量,而是团队在指定时段内可以提供的工作量,比如 5个人的团队工作21天,那么这个工作容量就是5*21=105人天。
在使用工作量时,注意区分毛时和净时,在选择净时的情况下,需要注意一天按多少小时来计,比如按5小时来计算,估算工作量达到50工时,如果1个人做的话,需要10天来完成。
问题6,在什么情况下使用直接工作量估算?
可以看到虽然以前也存在直接工作量估算的做法,但并没有得到大力的宣扬,在以前的软件工程教材里,一般很少提直接工作量估算。
从敏捷类开发方法开始起,直接工作量估算得到了宣扬,得到了更广泛的传播。
在敏捷类软件迭代开发当中存在对此方法的不少应用。
问题7,Story Point的特殊情况是什么?
Story Point的起源与理想工作日紧密相关,一般的,在开始时,团队会将估计一理想人日能完成的用户故事为一个故事点。
如果始终保持一理想人日对等于一个故事点,那么故事点估算其实是直接工作量估算。
但多数情况下,1个故事点对应的工作量是会发生变化的,随着团队的变化,对1个故事点所需要的工作量一般会减少。
有些团队会始终维护一套用户故事样例库,相当于用户故事的砝码,新的用户故事与样例库的用户故事进行比对,进而判定新用户故事的故事点数。
在具体比对上,常见的方法有 排序法,排序法一般利用斐波那契数列(1,2,3,5,8,15, …,?,无穷大),还有模仿T-shirt size估算,常见的,分成3到5档,比如 S、M、L、XL,或大、中、小,给每一档设定故事点数值。
可以看到排序法和T-shirt size模仿估算在本质上是一样的,T-shirt size模仿估算是排序法的一个实现。
这有样例库的做法得到的估算点数就是规模,值得注意的是 故事点所表达的规模是相对的规模。不同组织、不同团队的故事点是不可以比较的。这与诸如IFPUG、NESMA等等的功能点是不一样的。
4个国际软件功能规模测量标准的功能点是像“米”一样的绝对单位。就是说 在中国A公司的A1软件用IFPUG识别出了1000个功能点,美国B公司的B1软件也用IFPUG识别出的1000个功能点,那么可以说A1软件的规模与B1软件规模相等。而如果中国A公司的A2软件用Story Point识别出了1000个故事点,美国B公司的B2软件也用Story Point识别出了1000个故事点,那么,是不能说A2软件的规模与B2软件规模相等,两种不具备可比性,如果非要比较,那么需要分析A2和B2各自所依据的故事点样例或基准。
前面说到新的用户故事与样例库的用户故事进行比对,进而判定新用户故事的故事点数,目前这个比对并没有绝对的做法,常见不同的做法有:
1,是否考虑不同人做的影响
2,是否考虑实现的复杂度、难度
3,是否考虑新用户故事关联或依赖的事务
4,是否考虑有疑问的部分
目前业界对以上的问题并没有定论,各家组织或团队结合各自情况和理解各有各的选择。
因此,Story point具备在规模和直接工作量的两种形态之间变化的多态,具备巨大的灵活性,具体组织在采用Story Point时,可以做适应性的选择。
问题8,哪种方法更加准确?
没有结合具体情况,这个问题是无法回答的。
假设误差系数= 估算值/实际值。
估算值 = 实际值 * 误差系数
绝对误差 = 实际值-估算值 = 实际值 - 实际值 * 误差系数 = 实际值*(1-误差系数)
可以看到的一点是 敏捷小团队短迭代的实际值是不大的。 假设9个人的团队,迭代周期是3周,那么 实际值约在135人天范围之内。就算误差系数比较大,绝对误差也是有限的。
而传统瀑布型项目就是另外一个样子,比如时间跨度也许达到1年,总的人月数约是120人月,在这种情况下,就不难理解为什么存在多个组织来维护功能点定义,收集数据,给出需要指数运算的估算公式。因为就算误差系数小,由于基数大,所造成的绝对误差就比较大。
在敏捷开发方法里,常见的,采用扑克估算方式,这个方法可以驱动整体团队的智慧来确定故事点的大小,也能提高估算的精确度,而且也能澄清不同的理解,是非常值得采纳的一个方法。