# 估算

最近我把大量的时间花在了冗长的估算拖沓的估算讨论上,静心的将模糊的需求分解成详细的任务,糟糕的是因为不可避免的范围变更,导致我每天都得花很多时间去重新做项目甘特图,同时还要调整估算.这种传统的方式让我想换一种方式来完成这部分工作内容,这时候我发现了另一种估算方式--相对估算.

在我们软件行业,尤其是我就职的公司是一家非常传统的企业,有数不清的未知数在等着我: 技术一直在变,新需求不断涌现,任务之间有着错综复杂的依赖关系,外界环境因素对项目带来负面的影响.

# 我们为什么要估算?

估算的第一个原因是帮助我们做周全的决定.比如我想出去旅游,青海和日本我会选择哪一个? 当然两者都可能有,但都不能忽略两个最重要的因素--时间预算

我如何知道自己能不能负担这次旅行呢?我要考虑是否为长期旅行攒够假期(时间)或者有没有足够的预算,我要预算旅行的天数和费用,这个思考原则同样适用于我们在产品清单上的需求.

估算的第二个原因是设定目标.如果我给自己制定了一个最后期限,就会全力以赴确保达到目标.估算虽然有时候不完全准确,但估算和设定目标这个做法毫无疑问可以帮助自己保持专注并取得最大成果.

# 什么是相对估算

相对估算通常应用于产品列表层面,而不是在sprint列表层面.因为sprint列表里的条目是在单个sprint中的,需求可以定义得足够详细,所以我们也用传统的时间单位来估算.另一方面,PBI的定义相对宽松一些,而且加在一起需要好几个月的工作量,这样一来,我们很难甚至不可能根据时间来估算.

相对估算使用"比较"的原则,比"拆分"的原则更快,也更准确.也就是说,团队不是把需求拆分为一个个任务并估算任务大小,而是对完成一个新需求所需的相对工作和以前估算过的需求进行比较.

# 爬楼

假如我们有四栋楼.其中三栋是现代化的高楼大厦,一栋较老.它们的大小各不相同.我们现在要估算爬楼梯到达这四栋楼的楼顶总共需要多长时间.

如果我们从来没有尝试过这样的运动,就得考虑一些未知因素.比如,我们不知道自己的体力情况,也不知道在走楼梯的过程中需要处理哪些障碍.

遇到这种情况我们要怎么办呢?我们可以花时间数一遍每栋楼有多少层,然后估算趴那么多层需要多少时间.但是我不知道自己的体力状况,也不知道楼道的状况.这样的估算不仅花时间,而且如果我们假设有误差,得出的估算也会有巨大的偏差.

我们再换一种解决方式,首先我们先用"工作量级别"对大楼进行归类,最小的建筑物可以假设为10点这一类.再看一下二号楼,我们觉得它看上去是10点那栋楼的三倍大小,所以把它归为30点这一类.三号楼是比较老的楼排在中间,所以我们把它归到20点这一类,但由于它比较老旧,可能趴楼梯有风险和障碍,综合这些因素,我们给它25点.最后一栋是摩天大楼,是二号楼(30点)的两倍,所以它是60点这一类的建筑.

这些点数只是为了方便比较相对的估算标记,这些数字也没有任何具体的长度或时间单位,它仅仅只是分类的标记.

通过刚才爬楼的案例,我们可以快速估算出爬四栋楼所需要的工作量--不是绝对时间,而是相对的角度.这些信息是拼图游戏的第一块拼图.我们现在也许已经知道爬一栋楼和爬另一栋楼所需要的工作量之间的相对比较,但还需要估算出整个过程需要多少时间.

下一步我们要花一点时间实际检测一下自己的体力状况和某个有象征性特征的楼道情况如何.我们把这个实验定时为10分钟(我们选定的sprint长度),看看能爬多高.十分钟后,我们爬到一号楼(最小建筑为10点)的中间.有了这个信息就能知道了我们的速度,换个说法,我们在十分钟的sprint中能够完成工作.鉴于已经爬到了10点建筑的一半,所以我们可以说我们的速度是每个sprint 5点.

接下来我们计算一下爬到所有四栋大楼的楼顶需要多少时间. 10+30+25+60 = 125.然后我们带入速度,我们将25个点除以5点的速度,得到25个sprint.每个sprint是10分钟,那么我们就需要250分钟.我们可能还需要额外的50分钟作为额外的缓冲.最后我们估算300分钟或6小时可以完成这个任务.

# 软件相对估算

让我们把这个新概念应用到软件项目中来,我们需要估算完成所有PBI所需要的工作量,而不是估算我们的爬楼实力.

我们需要用三个因素来确定完成所有PBI需要多少工作量: 复杂度,重复性和风险.

复杂度: 例如我们一个PBI需要设计复杂的优化算法,这可能不需要写很多行代码,但需要大量时间进行分析和思考.

**重复性:**例如我们有一个PBI专注于用户界面,需要适用于多种浏览器的各个版本,虽然这个需求不复杂,但重复性很高,需要大量的试错时间.

**风险:**例如一个PBI可能需要和一个从来没有接触过的第三方产品对接,这是一个风险需求,也许需要大量时间来解决早期配合问题.

# 相对估算实践

为了把相对估算的理论用于实践,很多团队会玩一个很有意思的游戏,即规划扑克.

# 规划扑克

"规划扑克"是在"德尔菲方法"基础上发展而来的,这个方法可以用到跨职能专家团队所具备的宽广的洞察力,因此做出来的估算通常比一个人估算更准.

这个方法要团队用扑克牌一样的卡片来出牌,卡片上是用点数来代表故事大小,普遍使用的点数是斐波那契数列: 1/2,1,2,3,5,8,13,21,44,♾.

游戏通常按照如下顺序进行:

  1. 在团队要求澄清范围与预期收益之前,产品负责人描述优先级最高的PBI.对PBI描述和接收标准所做的任何修改都要逐步记录下来
  2. 一单可以开始估算,每个团队成员就挑一张最接近这个PBI所需工作量的卡片,把印有数字的一面朝下
  3. 每个人都选好自己的卡片之后,所有团队成员同时翻盘,亮出自己的卡片
  4. 如果大家意见不一致,最高值和最低值的组员就做一个简短的辩论,其他组员旁听
  5. 根据辩论中分享出的新的信息,团队再回到第二步
  6. 重复第2到5步,直到对这个PBI达成一致
  7. 给这个PBI分配一个值之后,用同样的方法从第一步开始讨论产品列表中的下一个PBI

有一个重要的要求是每个人必须估算整个PBI的工作量,而不只是估算自己和自己专业擅长相关那一块任务的工作量.比如程序员不只估算编程的工作量,还要估算测试和部署的工作量.

怎么才能做到每个人都参与估算自己不熟悉的领域呢?他们需要根据经验进行一个综合性的估算,即使他们没有做过多少测试,但也记得以前实现某个相似PBI时需要哪些工作.比如他们会想起当时虽然编程没有什么难度,但因为和他们用的第三方付费系统有各种集成点,所以测试简直就是一场噩梦.对于个人来说,通常认为他们只估算自己负责的具体功能,而且这是新团队开始估算时通常都会有很大分歧的典型原因.

通常建议再初始产品列表确定之后安排一次规划扑克会,以后每次有新的PBI加入产品列表,都可以做后续的扑克游戏或在极少数情况下需要重估.只有在一大类PBI突然变大或变小时,才需要重估.

讨论完之后,团队开始玩第一轮规划扑克,如果无法达成一致,建议尝试提出以下几个问题:

  • 你们有没有考虑到所必须的功能,而不是仅仅是个人的专长
  • 你们队段数的观点是很坚决还是比较温和?如果是后者,又有没有可能改变估值
  • 有没有人在两个数值之间摇摆不定?如果有,是否愿意同意大多数人的意见?

最后我们总结一下估算扑克的优势:

  • 能够快速估算长期产品列表,不要求有纤细规范和复杂的依赖性分析
  • 能够通过多样化只能专家提供更广的视野,确保估算不至于有太大或太小偏差
  • 能够充分利用完成过去工作中获得的知识
  • 能够让团队在相对枯燥乏味的任务中增加乐趣.

# 转向相对估算

有些团队喜欢使用一种校准方法是识别出成品列表中最小的用户故事,然后把它指定为初始的1/2点故事.一单确定下初始基线,团队就开始估算其他用户故事.这种方法虽然是有效的,而且表面看起来简单,但实际情况是他最终所花的时间可能远远超出开始的预期时间,首先团队要遍历整个产品列表,从中选出候选的用户故事,其次,团队还要就到底选用哪个用户故事作为基线达成一致.

# 使用历史数据

使用历史数据的目的是帮助找出已知工作量和新的斐波那契数列点值之间的对应关系.使用历史数据可以为团队提供两个明显的优势:熟悉和一致.

# 熟悉

任何团队都比其他任何人熟悉自己已完成的工作,而不是未来要做的工作.这种熟悉程度在做规划扑克时尤其有用,因为团队可以把将来未知的工作和过去已知的工作进行比较,而不是把未知的将来工作和另一个未知的将来的工作做比较.这种方法不仅可以去掉不确定因素,而且比较起来也会快很多,因为团队可以很容易想起历史数据

# 一致

历史数据构成一组基准数据之后,同样的基准可以用作这个团队的所有项目.早期所有的这个工作自然可以加速将来的估算,因为初始基准只需做一次,而不是没来一个新产品列表就重复一次.