4.有故障信息数据库吗
我并不在乎你说些什么。如果你正在开发代码(即使是只有一个人的团队),但是没有一个组织严密,并列举了代码中所有已知故障的数据库,那么分发出去的代码的质量可能是很低的。许多程序员认为能够做到在自己的头脑中放一份故障信息表。这是胡说!反正我一次记不住两条或者三条以上的故障信息,也许就在第二天早上或者代码分发的一刹那,将它们忘得干干净净。可见,绝对需要正式地保存一份故障信息记录。故障信息数据库可以很复杂,也可以很简单。一个可用的故障信息数据库必须至少为每个故障包含如下数据:
重现故障的完整步骤
预期功能
观察到的(故障)行为
要分配给谁
是否已修复
如果故障跟踪软件的复杂性是阻止你跟踪故障的惟一因素,那么建立一个包含上述关键信息的五字段关系表,然后开始使用它。
关于故障跟踪方面的更多内容,可阅读《故障轻松跟踪》一文
[1]。
5.在编写新代码之前修复故障吗
Microsoft Word的第一个真正Windows版本曾被认为是一个“死亡之旅”项目。它花费的时间不计其数,并且常常脱开正常轨道。整个开发团队行进在看不到尽头的工作泥沼之中,项目经过了延迟、延迟与再延迟,压力大得难以置信。几年以后,当这个响当当的物件终于分发下去时,微软将整个开发团队送到迦南去度假,从而坐下来做某种严肃而深刻的灵魂自我反省。
他们意识到,项目经理们一直是如此固执地坚持按时间表行事,以致使程序员只顾赶进度而编写出极其糟糕的代码,因为故障修复阶段并没有成为正式进度表的一部分。整个团队没有在缩减故障数量方面做出任何努力,而是与此恰恰相反。
整个情景演变为:一个必须通过写代码来计算文本行高度的程序员只是简单地给出“return 12;”这样的代码了事,然后就等故障报告出来,故障报告总是说他的函数不正确。到头来,进度表只不过成了一张功能故障列表。在尸检行业,这称之为无限缺陷法(infinite defects methodology)。
为纠正出现的问题,微软公司普遍采取了一种称之为零缺陷法(zero defects methodology)的措施。公司的许多程序员对此报以咯咯一笑,因为这听起来就像是一种单纯依靠行政命令就能减少故障数目的管理思想。其实,零缺陷意味着在任意给定时间点,最需要优先去做的事情是在写任何新的代码之前消除故障。下面说说这样做的理由。
一般说来,在修复故障之前等待的时间越长,付出的代价(时间与金钱上)就越大。
比如,当编译器捕捉到一个拼写或者语法错误,然后去修正它基本上是小事一桩。
在首次试图运行代码时所看到的错误,可以毫不费事地立即进行修正,因为所有代码在头脑中仍然十分清晰。
如果在几天前编写的代码中发现了问题,找到它确实需要花费一些工夫。不过,只要重新阅读编写的代码,就可以回想起所有的事情,从而在合理的时间里把它修正过来。
但是,假如在几个月以前写的代码中发现了问题,就可能已经忘记了代码方面的许多事情,要修复故障就困难多了。这个时候倒是可以去对别人的代码进行纠错,编写代码的人可能正在阿鲁巴岛(阿鲁巴岛是拉丁美洲荷属安的列斯群岛中的大岛,译者注)度假。在这种情况下,修理故障就跟从事科学工作一样:你得慢慢地、系统而小心翼翼地行事,并且不能确定要花多长的时间才能纠正错误。
然而,要是在已经分发出去的代码中找到了缺陷,那么要修复它所要付出的代价将是难以置信的。
这就是要立即修复故障的一个理由:因为这样做花费的时间较少。下一个理由与这样一个事实有关:预测要花多长时间去编写新代码比预测要用多少时间去修复现有故障容易得多。
比如,假设叫你预测要花多长时间去编写一段进行列表分类排序的代码,你一定能够给出一个相当好的估计。但是,如果叫你预测要花多少时间去修复代码在安装了Internet Explorer 5.5版本以后无法工作的故障,你恐怕连猜也猜不出来,因为你不知道(从概念上讲)故障出现的原因。很可能要用三天的时间去把故障跟踪出来,也可能只要两分钟就够了。
这里要表达的意思是,如果进度表包含了许多有待修复的故障,那么该进度表就是不可靠的。但是,如果你已经修复了所有已经知道的故障,并且剩下的就是编写新代码,那么进度表就是极其准确的。
关于将故障数目维持在零的措施有另外一个重大意义,可以对竞争做出快得多的反应。一些程序员一直将这看做是让产品做好分发的准备。然后,如果竞争对手加入一个“杀手锏”新功能来抢夺顾客,你就可以只去实现此新功能,并即时分发产品,而用不着去修复一大堆累积起来的故障。
6.有最新的进度表吗
这个因素促使我们按进度表推进。如果代码对业务显得十足重要,那么必定有许多关于它为什么对业务重要的理由可用以了解代码要在何时完成。程序员在制订进度表方面所显现出来的执拗,给他们留下了坏名声。“在该做的时候自然就做了!”他们冲着业务人员大声喊叫道。
遗憾的是,事情远还没有完。在分发代码之前,需要业务部门去很好做出的规划决策太多了,这包括产品演示、贸易展示与广告等。做这件事的惟一途径就是拥有一个进度表,并保证它始终反映最新的情况。
拥有进度表的另外一个至关重要之处在于,它首先迫使你做出将要实现什么功能的决定,然后强迫你拣出最不重要的功能,并加以剪除而不是滑入功能沼泽地带(也就是功能范围蔓延开来)
[2]。
持有进度表并不意味着必定显得困难重重。不妨阅读一下第9章,其中给出了一种创建大进度表的简单方式。
[1] 见www.joelonsoftware.com/articles/fog0000000029.html。
[2] 关于功能沼泽的定义,见www.netmeg.net/jargon/terms/c/creeping_featuritis.html。