估时不准是很正常的事情
“如果一个程序员告诉你他已经完成了 90% 的工作量,那么他还需要同样的时间完成剩下的 10%”。
软件项目延期和跳票是众所周知的事情,其中不乏知名项目。
刚毕业的时候,我在一家做系统集成的公司工作,我们定制了一套售票软件,为景区接入互联网售票方案。供应该软件的软件公司非常自信的说,这东西非常简单,最多 2 个月就能搞出来。这家公司小有名气,我老板对 2 个月交付深信不疑,于是张罗了接入的客户、市场的物料等。
不过还是没能逃过 90% 定律,2 个月交付的东西只能算作一个 Demo。于是花了另外一个月测试,修复问题和完善业务逻辑,又花了另外几个月时间响应对接客户的条件,才逐渐稳定下来。
行百里者半九十,软件开发也大体如此。开发者估不准工时常有,估准了才奇怪呢。
后来自己也做了软件工程师,参与 it 项目开发,项目延期也是非常常见的事情。
工时估算的前提是质量
IT 团队能准时交付是一项非常有价值的能力,哪怕交付时间长一点。计划两周交付,最后能准时完成,比承诺 1 周时间,但是花了三周才交付重要得多。
越是大项目,越是重要。大项目的各个组件可能会发生相互依赖。如果不能准时交付,就会付出团队等待的情况,那可是真金白银。
做过项目管理的都知道甘特图,甘特图的每个泳道表达了项目各项资源的进展和计划。然而,软件项目不确定性非常多,各种突发事件。如果能提高准时按质量交付,各个单位的等待成本会小很多。
关键的是,衡量是否准时交付的关键是质量,其次才是交付。先给一个 demo,然后再慢慢改 bug。这种 “准时” 的交付,还不如有一个明确的延期时间,本质上还是 “猛糙快”。
谈项目工时估算,前提是在满足质量要求的前提下,否则估时没有意义。
估算准确依赖工程能力
那么能不能提高软件工程工时的估算的准确性呢?其实是可以的,刚到 ThoughtWorks 的时候,参与了一个交付项目。在一个项目开始前就计划了项目结束的时间,以及下一个项目的计划和安排。结果让我非常吃惊,那个项目的结束时间,和预期只有 2 周左右。并且这两周是逐步减少开发人员,最后只有 1-2 个人负责最后一周的交接期。
这就是专业软件团队和小作坊的差别,在专业项目经理带领下能把 3 个月的项目估算,精确到 20 - 30 个人天。能把项目工时估算到这种程度,体现了 PM 的内功。
在一个敏捷团队,需要把工时估准,不在于 “估” , 而在于团队执行项目的稳定性。一般来说,准确估算工时需要考虑需求分析程度、任务拆分的合理性、技术方案的可靠性、团队成员的能力、外部依赖和环境,如果这个项目不是新项目,还需要考虑遗留系统改造的成本和数据迁移的成本。
需求和任务分析
只有需求分析非常彻底才能保证估算的输入条件。非专业的业务分析师,只能看到需求冰山水面上的部分。软件的特性、功能的复杂性等。
专业的业务分析师,不仅需要看待功能需求,并对功能需求的逻辑性考虑完备。比如用户需要一个 APP,他实际上还需要一个后台,对应这个后台会有不同的用户、角色等。
根据这些业务输出,拆分出任务,敏捷开发中我们叫做用户故事,一个用户故事代表一个合理拆分的业务逻辑。能被评估工作量,然后根据这个工作量来评估工时。
除了这些功能需求之外,还有非功能需求。客户不仅仅需要一个 APP,还可能需要的是一个安全的、高性能的、国际化的 APP,而这些往往被客户当做默认选项。
一些性能优化的指标需要分析,并考虑性能优化的任务工时;安全需求可能有 HTTPS 配置,防病毒扫描等,都需要考虑;国际化也是额外的工作量。
挖掘用户真实需求的目的是定义怎么才算完成(Define of done),如果没人说得清楚满足什么条件这个项目才算完,那么估算工时根本无从谈起。
彻底挖掘客户的真实需求是评估项目工时的首要条件。
技术方案和团队能力
技术方案和团队能力和项目时间估算很大关系。很多项目的时间估算都是技术经理或者 Teach lead 来完成,往往是他们按照自己的经验和能力进行计算。光是这样,很难算的准的。
团队有多少人?对这套技术方案的熟悉程度如何?方案是否会发生较大的调整。人越多,人员水平差距都为工时估计带来了不确定性。经验多的人来做方案,如果是他做过的相似方案,自然会估的稍准一点。但大多数情况下没有这么理想的场景。
要做好工时估算,需要结合技术方案和团队成员能力,而不是自己能干多少活儿,多快干完来算。
一方面,技术负责人需要安排相应的技术预研,走在实际编码的开发人员前面,探探路,验证方案的可行性、实施难度、风险。就像作战的侦查人员一样,我们把预研叫做 spike。 spike 需要输出一些结论、demo,支持项目的时间估算。
另外一方面,考察团队真实运作效率很好地方式是根据迭代做工时统计。按照两周为例,10 个人的团队是 100 个工时。如果按照之前的估算,2 周内需要完成的 100 个工时的任务,实际上只完成了 50 个工时。也就是进度只有 50%。
我这个算法比较粗糙,敏捷项目管理中还有更准确的速率计算方式。通过速率,就能对下一阶段的工时估算做出调整,并在工作量、人员上做出调整。
通过方案预研和速率计算是提高项目工时估算准确率的良好方法。
遗留系统和外部依赖
我常常花了一下午时间完成了某个特性升级的编码,但是花了一个月的时间才完成了线上平滑升级、数据迁移。
真正有经验的工程师都知道,方案设计的难点往往不在设计一个新东西,而在于演进一个老系统。遗留系统演进是不可避免的,这种历史包袱是造成工时估算不准的一个重要因素。
遗留系统演进带来的估算困难来源下面几个方面:
- 前置条件不满足或者很困难。客户可能觉得只是添加一个小功能,但是涉及数据库变更、API 升级。软件项目往往牵一发而动全身。
- 遗留系统代码难以理解,没有人说得清楚原委。这种系统往往伴随着重构,否则难以进行。
- 数据迁移的成本。例如,需求只是简单要求对用户的某些数据加密,实际工作包括了对存量数据的迁移。
- 临时代码的清理。遗留系统往往为三个状态,原始态-过渡态-最终态,很多人估算工时要么忘记了过渡态,就是忘记了最终态的时间成本。
不负责的猜想,有一些客户就是遗留系统演进不下去了,然后招标做新功能,实际意图是想乙方顺便消化重构的成本。总之基于遗留系统的二次开发都是一件困难的事情,能不接就不接吧。
另外,社会分工意味着一个人干不完所有的事情,IT 项目往往一个项目也不是独立的。大多数情况下需要和外部条件进行集成,这部分时间超出我们的掌控。
集成这件事的成本需要试主动集成还是被动集成来说:
- 需要等待别人提供服务,我们去集成。在估计工时的时候,一定要把对方的交付时间考虑进去,提前沟通,并建立契约。
- 提供给别人服务,被别人集成。这种情况估计工时,往往只是计算到 API 上线,实际上还需要考虑一定的支持、文档工作量。很少有一次到位的情况,大多要磨合一段时间。
集成充满了不确定性,估算工时时需要预留足够的集成空间,才能让工时估算更准确。
总结
项目工时估算是一个系统性工作,基本上很难有一个万能的方法。因此大多数情况下都是玄学,但是毕竟是 “估” ,也不能要求 100% 精确。
软件工程的估时更具有弹性,相对供应链管理的交付时间估算成本更低。做好估时,对减少项目运行成本和风险有巨大意义,工时估算的准确性也往往体现了一个 IT 团队工程能力。