# 二十四、绝不去做的事情,第一部 Netscape 6.0第一个公开的beta版终于出来了。5.0版从来没出现过,最后一版重大改版是 大约三年前发行的4.0版。在Internet世界里三年的时间长得可怕。就在这段时间中, Netscape只能无望地坐看市场占有率直线下降。 我这样批评他们在两个版本间等了很久,似乎有点惹人厌。他们并不是故意的这样的吧。真有人会故意这样做吗? 呃,没错,他们是故意的。他们做了一个每家软件公司都可能犯的一个最糟的策略错误: 他们决定把程序从头重写过。 Netscape并不是第一家犯这种错的公司。Borland买下Arago,想把它变成Windows版的dBase 时就犯了同样的错。这个注定失败的项目用了很长的时间开发,长到让它被微软的Access 彻底打败。Bor land后来又重蹈覆辙整个重写QuattroPro,还想拿重写的新功能来吓人。微 软几乎也做了相同的蠢事,想要在一个叫Pyramid的专案里重写Windows版的Word,不过这个 案子己经结束,并且消失在尘土之间。微软很幸运,他们从未停止使用原有的程序代码库, 所以一直有东西可以推出。因此这个错误只成为财务上的问题,而不是策略上的灾难。 我们都是程序员。而程序员在内心其实是个设计者,他们每到一个地方第一件事,就是先把 一切铲平然后创造伟大的事物。我们对修补改进和种种花床的渐进式革新不会感觉兴奋。 程序员总想把旧程序丢掉重新开始,其中的原因很微妙。他们会认为旧的程序是一团乱,不 过下面这有趣的观察指出他们可能是错的。他们会认为旧程序一团乱的直正原因是一个很基 本的程序设计原理: 读程序比写程序困难。 这就是程序再使用如此困难的原因。这也说明为何团队中每个人都喜欢用不同的函数把字符 串切成字符串数组。他们自己写自己的函数,因为这样比去弄懂旧程序更简单而有趣。 依据这个原则推论,你可以询问任何一个现役程序员正在用的程序代码。几乎每一个人都会 告诉你:「这真是一团乱,我真想把它丢掉重新开始。」 为什么会说是一团乱呢? 「嗯,」他们说:「看看这个函数。有两页那么长耶!这些东西都不属于这里的!我真不知 道里头一半的API是叫来做啥的。」 在Borland新的Windows版电子表格软件推出前,该公司有意思的创办人Philippe Kahnwas 在媒体上到处吹墟,说些QuattroPro是整个重写的,所以比微软Excel好上多少倍等等的鬼 话。全新的原始码哦!好像原始码会生锈一样。 新程序代码比旧程序代码好的想法显然是很荒唐的。旧程序代码己经被用过也被测试过。很 多问题都己被找出来并被修好。它并没有什么问题,不会因为在你的硬盘里放久了就生出新 的问题。你错得离谱了,宝贝!软件应该要像旧奔驰一样,光在放在车库里就会生锈吗?软 件应该要像泰迪熊那样,不用全新的材料做就不好吗? 回到那个两页长的函数吧。是的,我了解这只是个显示某个窗口的简单函数,不过却多了很 多怪东西而且没有人知道为什么。嗯,我会告诉你原因:它们是问题的修正。其中一个是南 西在没有Internet Explore「的计算机上安装时写的。另一个是对付内存不足时的问题。还 有一个是要应付档案放在软磁上,用户却中途抽掉磁盘的状况。LoadLibrary呼叫很难看, 不过却能让程序在旧版Windows 95上也可以执行。 里面每个问题都是在真实世界使用好几个星期之后才发现的。而程序员可能也花了好几天才 在实验室重现并予以修正。问题看起来很多,可是解决方法可能只有一行程序,甚至可能只 有几个字符,可是光两个字符的背后有着许多的时间和心血。 当你把程序代码丢掉从头重写时,其实是把这所有的知识都丢掉了。这所有己修正的问题, 好几年的写程序的成果。 你会让出市场领导地位。你会把两三年的时间当礼物送给竞争者。相信我,软件的一年可是 很长的。 你会让自己陷入一个极端危险的位置,到时候会有很多年都只能发行旧版程序,完全无法因 应市场需求的新功能而改变策略,因为你没有可以发行的程序。这段时期最好还是把公司收 起来算了。 你会浪费大量的资金去撰写己有的程序。 有代替的方案吗?大家都同意Netscape的旧程序似乎真的非常糟。嗯,或许它真的很糟,不 过你知道吗?它还是能在世界上数不清的计算机系统上运作的还不错。 当程序员照他们一贯的作风,说他们的程序是团神圣的垃圾时,其实里头会包含三种错误的 理由。 首先是架构上的问题。程序代码并没有被正确地安排。网络联机的程序代码会在莫名奇妙的 地方自己显示对话盒;而这应该是由使用接口来处理才对。你可以小心的搬动程序代码,重 构并修改接口,一次一个地解决这些问题。你可以找一个程序员小心处理好,再把所有修改 一次放回版本管理系统,就不会影响到其他人。即使很重大的架构修改,都不必丢掉程序代 码就可完成。我们花了好几个月重整Juno项目的架构:只是把东西搬来搬去,把程序代码清 理干净,建立合理的基脆别,并且在模块间建立明确的接口。不过我们非常小心的处理现 有的程序代码库,结果没有产生新问题也不必把还能用的程序丢掉。 程序员认为程序代码一团糟的第二个原因是效率不好。谣传Netscape的成像程序很慢。不过 这只牵涉整个项目的一小部份,你可以优化甚至重写这一小部份,并不需要把所有程序都重 写。在优化速度时,抓到1%的工作重点可以得到99%的效果。 第三个理由是说程序代码他X的丑。某个我做过的案子真的有一个叫FuckedString的数据类 型。另一个案子则是在开始时在成员变量名字前加底线1_’,后来却改用比较标准的1m_’。 结果一半的函数是用开头而另一半是用1m_’开头,看起来很丑。坦白地说,这种问题用 Emacs的宏功能五分钟就解决了,不需要从头开始。 你一定要记住,在要从头重新开始时,完全没有理由相信这次会做得比第一次好。首先你的 程序团队根本不可能和当初相同,所以并不会真的有「更多的经验」。你其实只会把大部份 的旧错重新再犯一次,另外再多加一些旧版本没有的新问题。 在面对大型商业应用程序时,做了就丢掉是很危险的旧咒语。如果你只是写程序做做实 验,想到更好的算法时大可把上星期写的函数丢掉,这是很正常的。想藉重构让某个类别更 容易使用,这也不会有任何问题,不过把整个程序都丢掉是个危险的愚行。如果Netscape 真的运用软件业经验成熟地管理,就不会把自己害得这么惨了。