# 二十四、绝不去做的事情,第一部
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 真的运用软件业经验成熟地管理,就不会把自己害得这么惨了。
- 第一部分 位与字节:编程实践点滴
- 一、语言的选择
- 二、深入底层
- 三、joel测试:改进代码的12个步骤
- 四、每一位软件开发人员必须、绝对要至少具备UNICODE 与字符集知识(没有任何例外!)
- 五、轻松写就功能规格说明书 - 第1节:为什么烦心?
- 六、轻松写就功能规格说明书 - 第2节:什么是规格说明书?
- 七、轻松写就功能规格说明书 - 第3节:但是……如何?
- 八、轻松写就功能规格说明书 - 第4节:技巧
- 九、轻松制订软件进度表
- 十、每日连编是朋友
- 十一、难伺候的故障修复
- 十二、软件开发中的5个世界
- 十三、稿纸原型开发
- 十四、不要被太空架构师所吓倒
- 十五、开火与运动
- 十六、人员技能
- 十七、源于计算机学科的三个错误思想
- 十八、二元文化
- 十九、自动获取用户故障报表
- 第二部分 开发人员的管理
- 二十、面试游击指南
- 二十一、重金激励害多利少
- 二十、二不配备测试人员的五个首要(错误)原因
- 二十三、任务换人有害无益
- 二十四、绝不去做的事情,第一部
- 二十五、冰川下的秘密
- 二十六、漏洞抽象定律
- 二十七、程序设计界的LordPalmerston
- 二十八、评测
- 第三部分 Joel对常态问题的遐想
- 二十九、RickChapman解读愚昧
- 三十、在这个国家狗是干什么的? 我们有多么天真?
- 三十一、作为哼哈二将,只管去做事
- 三十二、两个故事
- 三十三、巨无霸麦当劳与天才厨师JamieOliver
- 三十四、没有什么像IT看起来那么简单
- 三十五、提防非自主开发综合症
- 三十六、策略I:BEN&JERRY公司与AMAZON
- 三十七、策略II:鸡与蛋问题
- 三十八、策略III:让我回去!
- 三十九、策略IV:大件与80/20神话
- 四十、策略V:公开源代码的经济因素
- 四十一、墨菲法则肆掠的礼拜
- 四十二、微软公司是如何败北API之战的
- 第四部分 对.NET稍多的评说
- 四十三、微软精神失常了
- 四十四、我们的.NET对策
- 四十五、请问,我可以使用连接程序吗