[翻译]无痛项目进度表

原文 Painless Software Schedules

去年十月,美国东北充满了 Acela 的广告,这是一条从波士顿到华盛顿的新高铁。电视里、海报上和路边广告牌随处可见,您 可能 会觉得这些宣传会给美国高铁拉来更多的生意。

好吧,可能会,但可惜的是美国高铁没机会进行验证了。Acela 的运行一次又一次延期,甚至直到营销活动结束,高铁也没开通。这让我想起了曾经的一位市场经理,他的宣传工作取得了巨大的成功,但是距离产品上市还有一个月:“宣发完美!但是他妈的这东西根本 买不到!”

有些酷炫狂拽屌炸天的游戏公司喜欢在他们的官网上宣布他们的下一款游戏的发布时间是“制作完成后”。——进度表?哥们才不在乎什么进度表!哥们是最酷的游戏程序员!——好吧,但是大部分公司没资格这样干。您可以去问问 Lotus,当他们第一次对 123 3.0 版本进行宣发时,需要客户配置 80286 计算机,在当时这还是挺先进的稀有配置。随后他们的产品跳票了 16 个月(为了适应 8086 计算机的 640K 内存限制),等到他们完成时,微软的 Excel 已经发布了 16 个月了。(而且,讽刺的是,8086 在那时已经过时了)

在我写这篇文章时,Netscape 5.0 浏览器已经跳票两年了。其中大部分原因要归功于他们犯了一个自杀式的错误——抛弃所有的代码然后从零开始开发——同样的错误也注定了 Ashton-Tate、Lotus 和苹果的 MacOS 被扫入历史的垃圾堆。Netscape 眼睁睁的看着他们的市场份额从 80% 掉落到 20%,但是他们根本没法还击,因为此时此刻他们的核心软件产品已经被拆解成了一千个零部件平铺在地上等待组装。单单这一个错误就超过了其他所有的决策失败,成功的成为了 Netscape 引爆自己的核弹。(Jamie Zawinski 的那篇 举世闻名的小作文 中有详细说明)

因此,您必须制定进度表。即便不想做项目进度表已经成了所有程序员的共识。在我的经验里,绝大多数程序员会完全逃避制作进度表,少数程序员则是在老板的要求下勉强的、半推半就的、不情不愿的、制作了一份及其含糊其辞的进度表。实际上除了高层管理以外,从一开始就 没人拿这个进度表当回事 。(顺带提一句,这帮高管们还坚信 UFO 是真实存在的)

所以为什么大家都讨厌做项目进度表?有两个关键原因。第一,做项目进度表很痛苦。第二,大家都觉得项目进度表没用。如果说项目进度表最终没办法体现项目的进度,那为什么我们还要为此费力呢?既然大家都觉得项目进度表没用,而且随着项目的推进会错的越来越离谱,那为啥还要费力气做进度表呢?

以下是一个简单、无痛、有效的项目进度表编写方法

1) 就用 Excel。不要整 Microsoft Project 这样的花活。Microsoft Project 这种工具的最大问题是您需要花很多时间来处理所谓的“依赖关系”,也就是项目中不同任务的先后次序。而我发现在软件项目中依赖关系非常显而易见,没必要专门去进行管理。

Project 的另一个问题是他假设您需要一个“一键重排进度表”的按钮,这个功能则不可避免地将工作重新分配给不同的人。对于软件项目来说,这个功能是完全不可用的,程序员的工作具有极大的连续性,而非即插即用。让 John 去修复 Rita 的 bug 会比让 Rita 自己来修复多消耗 7 倍的工时。假设您安排您的 UI 师傅去处理 WinSock 问题的话,那么她大概率需要先花两周时间去学习新知识。总而言之,Project 是给盖大楼项目用的管理软件,而不是给软件项目用的。

2)保持简单。我的项目进度表的基础格式甚至您看一眼就可以记住,只需要 7 列:

如果您有多个开发人员,您可以给他们每个人安排一个 sheet,或者您也可以添加一列用来记录任务负责人。

3)每个功能都应由若干任务构成。功能就是类似于在“程序中添加拼写检查”这种东西。而“添加拼写检查”这件事则由一系列需要程序员执行的小任务组成。编写项目进度表最重要的工作就是要列出这些任务清单。核心规则包括:

4)让干活的程序员来评估工时。任何由管理层编造进度表,要求程序员去执行的项目都是注定失败的。只有具体去实施的程序员才能搞清楚完成任务需要哪些步骤,因此也只有干活的程序员自己能弄明白每个任务需要多长时间。

5)任务时间精度要足够小。这是让进度表能生效的绝招。您的任务必须按小时计时,而非按天计时。(当我看到一个进度表以天为单位安排任务,或者甚至以周为单位,我就知道这东西根本不真实)。您是不是觉得任务时间精度高的收益只是 统计更加精准?错了!大错特错!当您尝试将大块的目标拆分成精细的目标时,您会发现得到的结果和之前全然不同,不仅仅是任务被更加细分,甚至 总工时也全然不同。这究竟是怎么回事?

当您开始拆分细颗粒度任务时,您实际上是在强迫自己真正思考功能实现的步骤。编写 foo 子程序、创建某某对话框、读取 wawa 文件等等。这些任务的工时很容易预估,因为您真的编写过子程序、创建过对话框、也读取过 wawa 文件。

相反,如果您粗心大意的安排“整块”任务(“实现语法纠正”),其实表示了 您没有仔细思考过要做什么。而如果您没有思考过要做什么,那么您当然无法获得准确的工时预估。

根据经验,每个任务应该在 2 到 16 小时之间。如果您的进度表上有一个 40 小时(一周)的任务,说明您的分解还不够细。

拆分细颗粒度任务还有另一个原因:这将强迫您去 设计 该死的功能。如果您只有一个随手写的 “互联网集成” 功能而且您安排了 3 周的工时,哥们你完了。如果您 必须搞清楚需要编写哪些子程序,那么您就必须要 确定 这个功能内容。通过(被迫)在编写项目进度表时的提前计划,您可以排除软件项目中的许多不确定因素。

6)持续跟踪原始预估工时和当前预估工时。当您第一次将某个任务添加到进度表时,请估算任务需要的工时并将其填入原始预估(OrigEst)和当前预估(CurrEst)两列中。随着时间的流逝,如果您觉得某个任务所需的工时大于或小于您所想的,您可以随时更新当前预估的值。这是您通过时间学会工时估算的最好方式。大部分程序员不知道该如何预估工时,没关系,您只需要不断地尝试,不断地更新进度表,最终都能学会。(您可能必须砍掉某些功能或是延迟发布,但是进度表仍然在起作用,至少他能够告诉您何时需要砍掉功能或是做好延迟发布的准备)。据我观察,大部分程序员大约需要一年的时间来学会较为准确的评估工时。

在任务完成时,当前预估列和已用时间(Elapsed)列的值应当相同,而剩余时间(Remain)列则会自动计算为0.

7)每天更新已用时间。您无需掐着秒表编程,只需要在回家之前(或者对于那些极客就是在桌子下面睡觉之前),假装您已经工作了八小时,回头想想您今天做了哪些工作,然后在已用时间中把这八小时加上。剩余时间列则会被 Excel 自动计算。

同时,根据现实情况来更新当前预估工时。每天更新进度表大概只需要消耗您两分钟时间,这就是为啥我把这个方法叫做 无痛进度表方法——又快又简单。

8)为休假和节假日添加条目。如果您的项目需要一年的时间,那么每个程序员都可能会有 10 - 15 天用于休假。您应该在进度表中添加休假和节假日,以及任何其他的导致程序员不上班的事项。随后您可以通过加总剩余时间列后除以 40 的方式来计算出发布日期——也就是剩余多少周的时间,包含所有事情在内。

9)将调试时间加入进度表!调试时间是最难估算的。回头想想您的上一个项目吧。调试所用的时间很可能会是开发所用时间的 100% – 200%。调试必须在进度表中有一席之地,而且很可能是占用最多时间的内容。

调试时间是这样用的。假设有一个程序哥正在进行 wawa 功能的开发,原始预估工时是 16 小时,但至今为止他已经工作了 20 小时而且看起来还需要额外的 10 个小时。因此程序哥在当前预估列中输入 30 并且在已用时间中输入 20。

在项目快要到达节点时,所有这些 “延期” 加在一起可能已经积累了很多。理论上,为了赶上项目节点,我们必须砍掉一些功能。幸运的是,我们之前已经预留了一个测试条目,并且预留的时间非常充足,很适合被砍。

原则上,每一个程序员都应该在写编写代码后就地测试。程序员们永远不应该在还有 bug 需要处理的情况下去编写新的代码。bug 遗留的数量必须越少越好,有两个原因:

  1. 在写代码的当天修复 bug 更容易。而在一个月后,当您已经忘记代码具体如何工作时,修复 bug 可能会非常困难和耗时。

  2. 修复 bug 就像做科研,您无法估计何时会有突破并解决 bug。如果任何时候只有一两个未解决的 bug,就很容易估算产品的交付时间,因为剩余需要科研的内容就那么点。另一方面,如果您有数百或数千个未解决的 bug,就不可能预测他们何时能被全部修复。

如果程序员们总是一边开发一边 debug,那么为啥我们还需要为调试预留大量时间呢?好吧,实际上即使您在开发时已经修复了所有您已经发现的bug,到了每个里程碑节点的时候,您的产品仍将不可避免的会被测试人员(公司内部的或是 beta 客户)发现一些 真正难搞 的 bug。

10)将集成时间加入进度表。如果您的团队超过一名程序员,那么不可避免的,他们产出的内容会存在冲突。有可能是他们都为了类似的功能各自实现了对话框。需要有人负责检查所有的菜单、快捷键、工具栏等等…清理和组织大家随意添加的各种菜单项。当两个程序员一起提交代码时编译器可能会出现编译错误。这些都需要修复,而且应该作为进度表中的一个条目。

11)在进度表中加入缓冲(buffer)时间。事情的发展总是和我们预想的不同,至少有两种重要的缓冲您需要考虑。第一:为那些实际消耗时间比原始预估时间更长的任务预留缓冲。第二:为那些您没有考虑到的工作预留缓冲,例如管理层临时决定将 wawa 作为软件的重要功能而且必须在此版本发布。

您可能会发现:休假、节假日、测试、集成和缓冲的时间加起来比实际开发时间多得多。如果您对此感到惊讶,那说明您编程的时间还不长,对吧?忽视这些后果自负。

12)永远不要允许管理层压缩程序员预估的工期。很多菜鸟经理觉得通过压缩工期可以“激励”程序员来尽快完成工作,我觉得这帮人就是纯弱智。实际上当我的进度落后于进度表时,我只会感觉到沮丧、没动力、项目注定失败。进度表不是给这些弱智玩心理游戏的地方。

如果您的上级执意要您压缩工期,您可以试试这个办法:在进度表中创建一个新的列叫做 Rick 的预估工期(这里假设您就是 Rick),在其中填入您对项目工期的预估。此后把 当前预估时间 列交由您的上级处置,随便他怎么填。当项目结束后,再看看谁的预估时间更加接近现实情况。我发现只需要和上级 提及 这个想法就能有效地威慑他们,特别是当他们意识到这种比较实际上就是在 比谁工作的更慢 的时候。

为什么无能的领导总在试图压缩程序员的工期?

在项目开始时,技术管理人员和商务开会,最后列出一份 他觉得 能在 3 个月内完成的功能清单,但实际需要 9 个月。当您只需要考虑架构层面的东西而并不考虑所有的实现步骤时,往往您觉得需要 n 天的工作,实际上大约需要 3n 天。随后当您开始编写项目进度表时,您将所有的步骤都写入表中然后逐渐意识到所需的时间远远超过预期。现实情况逐渐浮出水面。

无能的领导这时候灵光一闪,心想:如果我能让程序员们工作得更快,那么我就能让他们在 3 个月内完成工作! 好吧,然而这并不现实。随后他又想到也许可以招聘更多人来工作,但招来的人需要适应,需要熟悉项目,在最初几个月的时间里这些新来的哥们往往只能产出 50% 的生产力(而且还得让现有的熟练工花时间带他们)。不管怎么说吧,据我观察,现在新招的程序员往往要半年时间才能达到满产状态。

您可以通过对程序严格考核来增加大约 10% 的产出,这带来的结果就是让他们筋疲力尽。收益很小,长期亏损很大,这种行为就像是农民把留种的种子吃掉一样愚蠢。

您也可以通过让程序员 996 来增加大约 20% 的产出。boom!bug 率超高调试时间翻倍半年内离职率激增,而且您失去的都是那些高产员工,留下一群工作表演艺术家陪您 996 奋斗(毕竟真正工作的大脑不可能一天高强度运行 12 小时)。最后您得到的是延期的项目、低效的团队、破产的公司。一种绝妙的因果报应的方式适得其反。

无论怎么样,您都不可能在 n 个时间里产出 3n 的工作量,如果您仍然坚信您可以,那么请赶快把您公司的股票代码告诉我,我现在就去做空。

13)进度表就像木块。如果您有一堆木块,然后无法把他们装进一个盒子里,那么您只有两个选择:要么换一个大点的盒子,要么就是放弃一些木块。如果您需要在 6 个月内交付产品,但您的进度表上却有 12 个月,您要么延期交付,要么就是删除一些功能。您就是没办法压缩那些木块,如果您假装可以,那么实际上您也只是在对自己看到的事实说谎,剥夺了自己 真正面对问题 的机会。

而且您也已经了解了,维护进度表的另一个好处是 强迫 您删除一些功能。为啥说这这是好处呢?假设您有两个功能:其中一个真的很有用而且会让您的产品走的更远(例如:Netscape 2.0 中的表格),另一个则是简单又好玩,程序员们非常想要加进去(例如:BLINK 标签),但是这玩意实际上没啥用,对市场也没啥帮助。

如果您没有项目进度表,程序员们总是会先去实现那些简单又好玩的功能。他们会在这些游乐场里耗尽所有的时间,一直到最后,您不得不为了那些有用又重要的功能延期。

而如果您制定了项目进度表,那么在工作开始前,您就会意识到您必须砍掉一部分功能(来保证交期),因此您当然会保留那些有用又重要的功能,砍掉那些简单又好玩的功能。通过强迫自己在功能之间做出选择,您最终会获得一个更强大,更好的产品,组合了最最重要的功能,而且能够按时发布。

我记得在开发 Excel 5 的时候,我们最初计划的功能列表无比庞大,会远远的超过预定的工期。当时我们觉得这些功能都是超级重要的功能!没有宏编辑向导我们怎么活啊?!

事实证明,我们别无选择,最终我们把进度表砍的只剩骨架,每个人都对这些功能被砍感到不快。为了安抚我们自己,我们告诉自己这些功能只重要性稍低,将延后到 Excel 6 再实现。

当 Excel 5 接近完成时,我开始和同事 Eric Michelman 一起制定 Excel 6 的规格。我们坐下来查看从 Excel 5 进度表中削减的"Excel 6"功能列表。我们完全震惊地发现,被削减的功能列表是我们能想象到的最糟糕的功列表。这些功能没有一个值得做。我认为即使在接下来的三个版本中,这些功能中也没有一个被实现。为适应进度表而筛选功能是我们能做的最好的事情。如果我们没有这样做,Excel 5 会花费两倍的时间,并包含 50% 无用的垃圾功能。(我完全确信这正是 Netscape 5/Mozilla 发生的事情:他们没有进度表,没有明确的功能列表,没人愿意削减任何功能,他们就是没有发布。当他们发布时,他们会有很多像 IRC 客户端这样他们根本不应该花时间的次要功能。)

附录:关于 Excel 您应该知道的事情

Excel 之所以成为处理软件进度表的绝佳产品,原因之一是大多数 Excel 开发者使用 Excel 的唯一目的就是维护他们的软件进度表!(他们中没多少人在运行业务假设情景分析…这里说的是程序员!)

共享列表 使用文件/共享列表命令允许每个人同时打开文件并同时编辑内容。由于您的整个团队应该持续更新进度表,这真的很有帮助。

自动筛选 这是筛选进度表的好方法,例如,您只看到分配给您的所有功能。结合自动排序,您可以看到按优先级排序的分配给您的所有功能,这实际上就是您的”待办事项”列表。很酷!

数据透视表 这是查看汇总和交叉表的好方法。例如,您可以制作一个图表,显示每个开发人员在每个优先级上的剩余时间。数据透视表就像切片面包和巧克力奶昔。您必须学会如何使用它们,因为它们让 Excel 的功能强大了一百万倍。

WORKDAY 函数 是Excel 分析工具包中的无痛进度表中获取日历日期的好方法。


[翻译]无痛项目进度表
https://vitsumoc.github.io/无痛项目进度表.html
作者
vc
发布于
2024年11月19日
许可协议