0. 我是前言
一个开发人员能否精确评估开发时间,是一件非常重要的事情。如果你掌握了这项技能,你在别人的眼里就会是这样:
1. 评估开发时间的重要性
首先,在一个项目中,所有的环节都是承上启下的,不管你是身处瀑布流团队还是敏捷团队,不管团队用的是 Sprint 还是 Kanban,上一个环节结束的时间节点正是下一个环节开始的节点。那么在一个项目或者一次迭代正式启动前,所有的环节都应该有个时间评估。
对于项目,合理的预估可以减低延期风险,促进高效协作。
对于个人,合理的预估能让你宏观把控,细节拆分,了解需求,合理安排工作。
2. 为什么评估不准?
首先我们要知道,“评估” 天生就会产生偏差。但是,我们可以通过科学手段无限消除偏差。
先来看一个有趣的例子:
从 A 地到 B 地,总共20公里。请你预估一下骑自行车过去得多久。
我:每小时骑行10公里肯定没问题,所以就预估2小时吧。
现实a:20公里都是乡间小路,用时4小时。
现实b:晚上十点出发,抹黑骑行,用时6小时。
现实c:刚出发就开始下大雪了,被迫停歇一天,用时15小时。
现实d:唯一的跨江大桥坍塌了,被迫绕行100公里,路上爆胎,用时24小时。
。。。
再看看一张很贴近日常开发的示例:
估算时间 | 程序员想象的 | 程序员没想到的 | 实际时间 |
30秒 | 只需改动一行代码。我知道怎么改,在哪里改。 | 切换分支,拉取代码,切换环境,编译。改动代码后测试,修改相关文档。 | 1小时 |
5分钟 | 小事一桩,只需要谷歌查一下文档,很快就修改了。 | 在搜索引擎上很难一次就获得正确信息。发现Stack Overflow上答案五花八门。上官网翻了半天才找到相关文档,按照文档说明修改之后发现结果不对。 | 2小时 |
4小时 | 根据UI设计图,我知道有个第三方UI控件可以实现。 | 这个第三方控件和UI设计上的动画效果不一致,不能通过设置属性来改变动画。需要更改控件源码,或者寻找别的控件。 | 1-2天 |
2天 | 只需要实现一个简单的页面,然后从后端获得一次数据,展示出来即可。 | 如果请求失败,页面得显示一个提示。如果API请求token失效,需要更新token并且重试一次。Staging环境很难用,需要后端配合手动配置数据。 | 3-5天 |
5天 | 我知道这个功能比较复杂,大概需要改动三个模块。虽然你我还没有具体思路,但是我不能说我不知道,一周时间应该够了。 | 需求细节没有了解清楚。这个任务已经太大,不可控因素很多,需要拆分任务。由于历史原因,实现某个功能点很麻烦,牵一发动全身。或许架构师会发现一种很简单的方法来完成它。 | 3-20天 |
图3. 预估示例
是不是很真实?
从以上两个例子可以看出,导致预估不准确的原因有如下几种:
- 想当然
- 经验缺乏
- 依赖的不确定性
- 对需求和上下文了解不清楚
总之就是,假设不成立。
3. 不同的预估标准
3.1 以 Point 为单位
敏捷开发中,是以 Point 为单位评估一件事情的「复杂度」。一般使用菲波那切数列(1,1,2,3,5,8,13,...)中的数字。
「复杂度」的评估标准应该提前拟定好。要知道,「复杂度」仅仅体现事情的复杂度,不与个体的能力绑定。
一般迭代周期是固定的,如果知道团队的 Capacity,那么就能算出这次迭代可以完成多少个 point。
例如,迭代周期是20个工作日,Capacity 是 0.8,团队成员 4 人,那么这次迭代就可以完成 20 x 0.8 x 4 = 64 个 point。
3.2 以 Day 为单位
在瀑布流开发模式中,一般以 Day 为评估单位,并且和个人能力挂钩。所以可以直接估算出开发时间。
任务数量确定,评估出开发时间后,就可以算出交付日期。这个就不展开讲了。
不管是敏捷开发,还是瀑布模式开发。他们在时间预估上只是形式不同。
4. 如何科学地预估
上面提到过,评估是准确是因为很多假设不成立。那么如何做到假设成立呢?这就需要提高多个维度的认知。
4.1 提高需求认知 - 任务拆分
我们需要把任务拆分的尽可能小,以敏捷模式为例,一般 1 到 8 个 point 为宜,尽量不要超过 8 个 point。如果某个 story 超过 8 个 point,那么这个 story 必然很笼统,包含了太多的内容,估点肯定不准确。这时可以要求 PM 或 BA 去拆分这个庞大的 story。
拆分任务的时候,也是对需求详细了解的过程。对于不明确的地方,一定要和 PM 或 BA 沟通清楚。让一个 “事务” 变成一个个可执行且明确的 “任务”。
4.2 提高技术认知 - 做 Spike
对于开发者来说,不是所有的技术点都了然于胸。对于不确定的技术点,应该提前调研,可以建 Spike ticket 专门去做调研。进行可行性验证后,再基于调研结果做时间估算。
4.3 提高时间认知 - 计算有效时间
一天工作八小时,但你不可能专注地连续八小时在编写代码。一天的工作中,有开会、讨论、阶段性休息(刷新闻、喝咖啡、发呆)的时间开销,真正有效时间其实不足六小时,杂事多的话可能有四五个小时的有效时间。如果你是 Teach Lead,有效开发时间更少。
还要考虑人员请假和人员变动的时间开销。
虽然在敏捷模式下以「复杂度」为单位估算,但我们仍然需要清楚有效时间。这有助于我们计算 Capacity。
4.4 提高风险认知 - 合理预留 Buffer
自身风险:虽然做了调研,但也避免不了在工程中实践的时候不出问题,这是技术实践中的风险。
其他团队的风险:比如说前后端 API 联调,前端和后端团队都是对方的风险。后端开发人员告诉前端所有接口都已准备好并且自测了,但是当你去调用的时候发现有各种问题。(只是个例子,不针对后端)。还有需求改动。大的改动当然是不允许的,但是小改动往往不可避免。
面对这些风险,如何应对?
预留 Buffer !也可称为“容错时间”。这是在合理认知风险和认知时间的基础上进行余量预估,可不是随便增加预估量嗷。
具体要根据团队的沟通成本、配合默契度、依赖程度进行估算,一般在15%~25%之间(主观经验值,无从考证)。
4.5 回头看
一项能力的建设过程,都是不断反馈的过程。不同的项目不同的开发团队,往往评估策略是有差异的。所以我们要通过回头看,不断校正,逐步趋于精确。
预估 -> 实际用时统计 -> 回顾分析。不断练习,积累经验, 预估时间会越来越接近实际用时。
5. 结束语
Robert C. Martin 说:“Just as the Hare was overconfident in its speed, so the developers are overconfident in their ability to remain productive.” 是的,我们总是过于自信,很多时候在预估时间的时候体现的淋漓尽致。在多次交付延期或被迫加班之后,我们会逐渐趋于成熟,心里默念:谦和朴诚,保持敬畏。
最后,虽然有些团队是不要求严格预估时间,但是作为开发者,我们自己心里得有数,请养成这个习惯。