软件工程 估计方法
上回书说到 -
一个小组的同学 (6-8 人) 决定要徒步遍历中国陆地边界, 假设供给装备齐全, 估计需要多长时间?
用什么样的办法能让同学们方便地交流各自的估计, 最后到达大致理性和统一的共识?
一般这个时候教室里一定非常热闹, 大家各抒己见, 争执得不亦乐乎。 但是最后往往谁也说服不了谁, 还有一些同学无动于衷, 觉得无从下手, 干脆不参加讨论。 在这种情况下, 可以考虑通过 Wide-band delphi 来达到快速沟通和达到意见的一致。
网上有不少关于这类方法的介绍:
http://drdobbs.com/article/printableArticle.jhtml?articleId=184414570&dept_url=/ (Dr. Drobb’s)
这个方法看起来复杂, 其实挺简单的:
1) 找到一个主持人 (facilitator/moderator)
2) 主持几轮讨论, 每一轮统计大家的估计, 并且询问大家估计值的前提假设是什么, 找到合理的假设, 然后继续。
例如: 第一轮, 大家的估计和假设是:
a) 300 年 假设: 要按照边界走, 爬到珠穆朗玛峰就挂了
b) 2 年; 假设: 两万多公里的陆上边境线。参考红一方面军在长征时候的记录,12个月走1万两千公里。所以2年即可。
c) 5 年; 假设: 3 万公里, 一年工作 300 天, 每天20公里,
d) 1 年; 假设: 边界大概有10个省份, 每个省份在当地公安边防的带领下, 一个月就搞定了。 有两个月用于和各地政府取得联系。
e) 5 个月 假设: 南宋后再无中国, 只好沿着南宋的边界走, 走走玩玩, 很快就走完了。
f) 不可能 假设: 被有关部门请去喝茶
[我在微博上看到还有人说 50 天的, 不知道他的假设是什么样子…]
…
大家对各自的假设做了分析, 得出了新的共同假设:
沿着边界 = 离边界最近的公路或小路走, 青藏高原可以绕一下, 不必亲自到每一块界碑跟前拍照留念。 不过还得自己走。
陆地边界 = 中国现在的边界, 不是南宋的。 约等于2 万公里
在这样的前提下, 大家又有新的一轮估计:
… …
然后又澄清一些假设,
… …
最后大家的估计收敛到一个大家都比较满意的精度数值。于是估计就结束了. 注意在精度上, 大家不必太拘泥, 根据这个题目的情况, 用月做单位即可。 不必争论到底会用 1002 天还是1003 天。
主持人要记住在每一轮的估计中, 推动数值收敛, 这要求大家的假设 (也就是用户需求分析) 也要收敛, 不要天马行空。
注意, 最后得到的估计数值, 也许和某人最初提出的数值很接近, 但是这意义并不大, 因为最后达成的假设也许和最初的假设大相径庭。 Wide-band delphi 的目的不是比谁的第一轮估计猜得准, 而是在较短的时间内让团队充分沟通, 交换意见。
软件开发的一个特点是, 软件项目的确有不少东西可以重用别人的结果, 但是项目中最有价值的部分, 别人都还没做过, 还得自己动手. 这就要求我们去探索, 发现这样的工作到底需要多长时间。 问题是 - 探险者总是高估自己的能力,低估未知的困难 - 不然他们就不会出门探险了!
据说, 早期的西班牙探险者到美洲达科罗拉多河大峡谷的时候, 站在峡谷南岸俯瞰深谷中蜿蜒的河流, 他们觉得那不过是一条细细的小溪而已。 他们估计用不了一天的时间就能跨越, 于是大队人马开始出发。 等他们下到山谷的一半, 才发现河流湍急, 自身的装备不够, 人困马乏, 只好又悻悻返回, 同时已经累得半死。
我们在做项目的时候, 也有很多次发现原来估计很容易的地方原来 “水很深”, 往前走, 也许会被淹死, 往回退, 会耽误大量的时间。 这时候大家心里都暗想 - 当时要是在项目计划的时候多做深入分析和估计就好了! 但是回过头来, 对于这种情况, 大家如果坐在峡谷边 wide-band delphi 一整天, 也依然会得出非常乐观的结论,因为没有人提出不同的 “假设”。 这时候, 我们可以考虑参考前人的经验, 打听一下当地人跨越大峡谷要几天。 有些事情花的时间是客观规律, 不是由个人能力决定。 例如生一个小孩大约需要10个月, 这个估计和你的 S 是大号, 中号, 还是小号无关, 和婚礼来宾的数量也无关。 要是还不满意怀孕时间长, 再加上数十个精壮男子帮忙, 也无济于事。
另外一个办法是快速原型法 - 用一两个先锋去探路。 例如一个项目如果能用上 Microsoft Azure 平台, 那貌似会给我们带来很多好处. 如果你光看 Azure 的宣传资料, 你觉得这简直太容易了, 咱们赶紧上马! 且慢, 这时不妨派一个人写一个简单的Azure Hello World 应用, 实际看看开发/调试/部署/支持的情况如何, 这样才能给项目估计提供更好的数据支持。
我自己在长期的革命斗争中, 摸索出一套经验公式: 你问一个开发人员两件事 – 对某件事的估计时间 X, 以及他做过类似开发工作的次数 N. 那么他最终需要的时间
Y = X +/- X/N //注: 中间的 +/- 表明或者加上, 或者减去。
例如果冻估计某个模块需要 3 天, 但是果冻从来没有做过, 那么这件事情实际花费的时间有两种可能 Y = 3 +/- 3/0.
就是说, 这事情也许是 (3 + 无穷大), 在项目时间内压根就做不了。 例如一个学生团队一度想做 “用玩家的人脸做拳皇游戏”
或者是 (3 - 无穷大), 不但不用做, 而且这个员工会搞出很多新的bug 来, 让团队花更多的时间来处理, 把项目拖垮.
比如果冻说要实现网络用户的管理, 结果发现Asp.net 早就实现了. 但是果冻不服,非得要自己写一个。 结果写得漏洞百出, 很多其他员工来帮他擦屁股。 最后把他的代码扔了, 用标准控件来实现。
当 N 等于 1 的时候, 一项工作估计的实际花费范围是 [0 .. 2X], 如果员工一直做类似的项目, 他们的 N 值都在 1 以上, 估计变化的范围会越来越小, 准确度越来越高。当然, 技术在变, 市场在变, 员工的心态也在变, 员工是不甘于, 也不能一直做雷同的项目的。
一个案例: 大牛在完成一项任务, 他原计划 3 天完成, 现在是第三天的下午, 他马上就可以做完. 但是在实现功能的过程中, 他越来越意识到自己原来的想法不是最好, 他应该采取另一个办法, 才能避免后面集成阶段的额外工作. 但是他如果现在就改弦更张, 那势必要影响自己原来估计的准确性. 这样他的老板, 同事会因此看不起他? 如果他按部就班, 最后整个团队还要花更多时间在后续集成上, 但是就不是他个人的问题了. 怎么办?
整个软件项目的时间估计也可以从两个步骤来看 -
a) 自底向上 团队成员各自估计底层模块和单个功能 (和单元测试) 所需的时间, 再加上集成, 及基本测试的时间, 就是大概的开发时间。 这还没有考虑各个模块之间的相互依赖性.
b) 回溯 团队从整个项目最终交付之日往回倒推 -
如果在十一就要交付整个软件, 那么九月一号就要完成基本测试
如果九月一号要完成基本测试, 那么八月一号就要代码完成 (Code Complete)
如果八月一号要代码完成, 那么我们要有16 周的开发任务, 那意味着我们四月一号就要开始, 而且四月一号要有第一批设计规格说明书 (spec)
我倒! 今天已经四月七号了! 你还在看博客!
在敏捷开发的项目中, 团队一般不过分强调 “估计”的价值,因为它就是一个“猜”字。 “猜得准”不是团队的目标。 团队的目标是把软件写出来, 让用户满意。 如果猜错了,没关系,微调项目进度即可,不要为了“猜得准” 而踌躇不前; 或者为了让当初的猜测看起来靠谱而不如实报告进度。
在敏捷的开发流程中, 还有不少看似山寨的办法, 我接触到的有:
估计扑克牌 – 扑克牌上面是1, 2, 3, 5, 8, 13, … 等数字, 大家出牌来估计某功能花费的时间。 这副牌我给了我们项目的PM, 她拿去打拖拉机了。
划拳估计法 - 几人一声呐喊, 同时出拳, 几个手指代表几天, 我们项目组还没有正式演练过.
t-shirt 尺寸法 – 用 S, M, L, XL 代表估计的时间长度, 对于尺寸超大的任务, 要考虑把它们分解为比较细小可掌控的小任务.
这些方法都是强调快速得到粗粒度的估计, 然后进入实现阶段. 一个团队经过一次里程碑之后, 再回过头看看原来的估计和实际花费时间的差距。 经过一两次里程碑, 成员们就可以了解在我们项目中, 一个尺寸为 S 的任务大概要多少天。
关于时间估计, 这里有更多相关内容:
http://www.pmhut.com/agile-estimating-%E2%80%93-estimation-approaches
回到上一个博客提到的目标, 决心和估计的区别, 当一个程序员果冻听到大老板说 - 果冻, 这个项目十一要交付使用, 你估计能行么?
果冻首先想到的不是用哪一种时间估计方法, 而应该反问 - 老板, 您已经给了一个商业目标, 现在你是想听客观的估计呢? 还是我主观的决心?
老板一定会对果冻另眼相看的
作者: SoftwareTeacher 发表于 2011-04-06 22:50 原文链接