第一章 项目管理失当
第一节 2001年6月1日:“开发时间表、飞猪和其他幻想”
一匹马走进酒吧,说道:“我能在两天内完成那个功能。”开发成本计算和时间表是个笑话。相信它的人,要么是傻瓜,要么是初出茅庐的项目经理。这不是模糊科学,这是瞎编。不错,的确有人相信编码工作可以被精炼成一个可预见进度和质量的可重复的过程,那我儿子至今还相信牙仙子呢!事实上,除非你只需编写10行那么长的代码,或者代码可以直接从以前的工作中复制过来,否则你不可能知道编码会花费多长时间。
作者注:项目经理(Program Manager,PM)有很多职责,其中职责之一是说明最终用户体验和跟踪所有项目的整体进度。这种角色是必要的,但他们常常不讨开发者的喜欢,因而也很少得到开发者的尊重。真遗憾,项目经理是一份很难做好的工作。但是,对于Wright先生来说,项目经理仍然是一个有趣并且容易达到的目标。
译者注:①关于牙仙子(Tooth Fairy)。美国人有个信仰:小孩子换牙时,父母会告诉他把牙齿用信封装好,放在枕头下,早上起来的时候牙仙子会用钱跟他换牙齿。这钱当然是父母给的,用来鼓励小孩子拔牙。牙仙子在美国是人尽皆知的,虽然只是一个“善意的谎言”!②关于飞猪(Flying Pigs)。猪会飞吗?美国人常用此来比喻离奇荒诞之事。
里氏震级估计
译者注:里氏震级(Richterscale)是地震等级的一种数值标度,分1~10级,每上升一级,强度增加约60倍。
当然,你可以估算,但估算出来的时间是成对数关系的。有些事情需要花费几个月,有些事情需要几周,有些需要几天,有些需要几个小时,有些则只需几分钟。而我跟我的项目组项目经理(Group Program Manager,GPM)一起给一个项目做时间安排时,我们对每个功能使用“困难/中等/容易”3个等级来评估。“困难”意味着一个全职开发人员需要花费整个里程碑时间;“中等”意味着一个全职开发人员需要花费2~3周时间;“容易”意味着一个全职开发人员需要花费2~3天时间。没有其他等级了,也不做精确的时间表。为什么呢?因为我们俩知道,我们无法预测更精确的时间了。
在我的记忆里,除了一系列里程碑、测试版、正式版发布等“项目日期”外,我没有在开发时间表上为各个功能规定交付日期。一个好的开发时间表应该是这样的——它只是简单地列出在每个里程碑期间需要实现的功能。那些“必须有”的功能放在第一个里程碑期间内并且都是要完成的,如何完成则是根据开发人员的数量和“困难/中等/容易”等级;“最好有”的功能放在第二个里程碑期间内;“希望有”的功能放在第三个里程碑期间内;除此之外的所有功能统统不做。通常情况下,如果到了第三个里程碑期间的第二周,仍然有较多“最好有”、“希望有”的功能没有实现,这时候大家都很惶恐,你就要把所有“希望有”的功能扔掉,并且“最好有”的功能也只保留一半。
作者注:里程碑的设定因团队而异,也因产品而异。典型情况下,一个里程碑跨越6~12周不等,是“项目日期”,是组织(50~5 000人)用于同步工作和复审项目计划的时间点。在里程碑期间,各个团队(3~10人)可能使用他们自己的方法来跟踪具体的工作,比如简单的工作条目(workitem)清单、产品备忘录及实施进程图。
译者注:产品备忘录(product backlog)是在项目开始的时候,需要准备一个根据商业价值优先级排好序的客户需求列表,是一个最终会交付给客户的产品特性列表,涵盖所有用来构建满足客户需要的产品特性,包括技术上的需求。实施进程(burndown)图是敏捷软件开发方法Scrum中常用的一种图表,用来展示剩余待完成工作与时间之间的关系。时间标识在横坐标轴上,未完成工作标识在纵坐标轴上。
风险管理
这才是我要引出的主题。在开发成本计算和时间安排上不能只盯着日期或时间不放,应该关注风险管理。我们通过软件的功能和特性来取悦客户,不管这是个软件套包还是网络服务。这里的风险指的是,我们未能在合适的时间,将符合质量要求的功能集合交付到客户手中。
一个好的开发时间表通过优先处理关键功能来管理风险。这些关键功能是能让客户满意的最小功能集合。通过“困难/中等/容易”这种评级方法,可以判断出在这个最小集合中包含哪些功能是切实可行的。其他的功能按照优先顺序和一致性原则依次加入。
然后你开始编写代码,并且看着功能实现从困难转向容易,又从容易转向困难。通过集中所有必要的资源,以降低不能按时交付高质量的“必须有”的功能的风险,其他的都是次要的。你还可以将不紧要、但又不失挑战性的项目交给实习生去做。
作者注:具有讽刺意味的是,几乎所有的工程师和经理都赞同优先处理“必须有”的功能,但事实上很少有人真的这么做,因为“必须有”的功能通常是乏味的,比如安装、软件工程创建、向后兼容性、性能优化和测试套件等。然而没有这些功能,你的产品根本就无法发布。因此,产品发布往往是因为这些问题而一拖再拖。
一定要破除“功能交付日期”的神话,因为开发人员专注于这种日期的时候会破坏风险管理。真正要关心的日期只能是“项目日期”,比如各个里程碑、测试版,等等,而绝不应该是“功能交付日期”。项目日期之间一般都有较长时间的间隔,而且这种日期不会很多。管理这几个日期要容易得多。如果要求开发人员在某个日期之前一定要实现某个功能,当他们不能按时完成时他们往往不会告诉你,而是对你说“我正在加紧做……我会加班……”之类的话。
在软件开发过程中进行风险管理,我们还要特别注意以下几个因素:一个是过度劳累的员工,一个是匆匆忙忙实现的、质量很差的功能,再一个就是你花费几周的时间且动用2~3位甚至更多的高级开发人员去解决一个棘手的问题。如果你的开发人员是在围绕“功能交付日期”付出大量的努力,而不是帮助你在产品的关键功能上降低风险,那么真有可能浪费时间了。
客户赢了
一个产品的成功与否,取决于你对关键功能的风险管理能力。当你给你的开发团队解释清楚这一点之后,情况就完全不一样了。当然,额外的功能可以锦上添花,但最关键的还是要专注于存在风险的地方,充分沟通,并一起努力把它们解决掉。
当所有人都理解了目标,所有人都能比以前工作得更好。每个艰巨任务的完成都能鼓舞士气,即使初级员工也会因为成熟的决议而得到回报。最终,我们的客户是大赢家,因为他们得到了真正想要的功能,并且产品质量也是他们当初所期望的,而不是一些勉强实现的、质量不能保证的垃圾。
顺便提一句,我对开发时间表的所有论述,对于测试时间表同样适用。