“你永远不应该做的事”(2000)

2020-07-04 01:57:50

Netscape 6.0终于进入了它的第一个公开测试版。从来没有5.0版本。上一次发布的主要版本是4.0版,几乎是在三年前发布的。在互联网世界里,三年是非常长的一段时间。在此期间,网景无奈地袖手旁观,因为他们的市场份额直线下降。

批评他们在两次发行之间等了这么久,我有点自命不凡。他们不是故意这么做的,对吗?

嗯,是的。是他们干的。他们犯了任何软件公司都会犯的最严重的一个战略错误,从而做到了这一点:

网景并不是第一家犯这种错误的公司。Borland在收购Arago并试图进入dBASE for Windows时犯了同样的错误,这是一个注定要花费很长时间的项目,以至于Microsoft Access吃了他们的午餐,然后他们再次犯下了同样的错误,从头开始重写Quattro Pro,并以其功能如此之少震惊了人们。微软几乎犯了同样的错误,试图在一个注定失败的名为金字塔的项目中从头开始为Windows重写Word,但该项目被关闭,被扔掉,并被扫地出门。对微软来说幸运的是,他们从未停止在旧代码库上的工作,所以他们有东西可以运送,这使得这只是一场金融灾难,而不是一场战略灾难。

我们是程序员。程序员在内心深处是架构师,当他们到达一个站点时,他们想做的第一件事就是用推土机把这个地方夷为平地,建造一些宏伟的东西。我们对渐进式的翻新并不感到兴奋:修修补补、改进、种植花坛。

程序员总是想扔掉代码重新开始,这有一个微妙的原因。原因是他们认为旧的代码一团糟。这里有一个有趣的观察:他们可能是错的。他们认为旧代码一团糟的原因是因为编程的一个基本的基本法则:

这就是代码重用如此困难的原因。这就是为什么团队中的每个人都喜欢使用不同的函数将字符串拆分成字符串数组。他们编写自己的函数,因为这比弄清楚旧函数是如何工作的更容易、更有趣。

作为这一公理的推论,您现在几乎可以向任何程序员询问他们正在处理的代码。他们会告诉你:“这是一大堆毛茸茸的乱七八糟的东西。”“没有什么比扔掉它重新开始更好的了。”

“嗯,”他们说,“看看这个函数。它有两页长!这些东西都不该放在里面!我不知道这些API调用中有一半是用来做什么的。“。

在Borland新的Windows电子表格发布之前,Borland的多彩创始人菲利普·卡恩(Philippe Kahn)在媒体上被大量引用,吹嘘Quattro Pro将比Microsoft Excel好得多,因为它是从头开始编写的。全新的源代码!就好像源代码生锈了一样。

认为新代码比旧代码更好的想法显然是荒谬的。已使用旧代码。它已经过测试了。已经发现了很多错误,并且它们已经被修复。这没什么不对的。它不会仅仅坐在你的硬盘上就能发现错误。正好相反,宝贝!软件是不是应该像一辆老式的道奇飞镖,只是放在车库里就生锈了?软件是不是就像泰迪熊一样,如果它不是用全新的材料制作的,那会不会有点恶心?

返回到两页函数。是的,我知道,这只是一个显示窗口的简单功能,但是它上面长出了一些毛发和东西,没有人知道为什么。好吧,我来告诉你为什么:这些都是错误修复。其中一个修复了南希试图在没有Internet Explorer的计算机上安装该软件时出现的错误。另一个修复了在内存不足的情况下出现的错误。另一个修复了当文件在软盘上,用户从中间拔出磁盘时出现的错误。LoadLibrary调用很难看,但它使代码可以在旧版本的Windows95上运行。

这些漏洞中的每一个都在现实世界中使用了数周后才被发现。程序员可能花了几天时间在实验室重现错误并修复它。如果它像许多错误一样,修复可能是一行代码,甚至可能是几个字符,但这两个字符花费了大量的工作和时间。

当您丢弃代码并从头开始时,您就是在丢弃所有的知识。所有这些收集的错误修复。多年的编程工作。

你正在抛弃你的市场领导地位。你给你的竞争对手送了两三年的礼物,相信我,这在软件年中是很长的一段时间。

您正在将自己置于极其危险的境地,您将在几年内发布旧版本的代码,完全无法进行任何战略更改或对市场需要的新功能做出反应,因为您没有可发布的代码。你不妨在这段时间内关门营业。

还有其他选择吗?人们的共识似乎是,旧的Netscape代码库真的很糟糕。嗯,可能很糟糕,但是,你知道吗?它在很多现实世界的计算机系统上都运行得非常好。

当程序员说他们的代码一团糟(一如既往)时,有三种事情是错误的。

首先,存在架构问题。代码没有正确分解。网络代码从无到有地弹出自己的对话框;这应该在UI代码中进行处理。这些问题可以通过仔细移动代码、重构和更改接口来解决,一次一个。它们可以由一个程序员仔细地工作并一次全部签入他的更改来完成,这样就不会干扰其他人。即使是相当大的架构更改也可以在不丢弃代码的情况下完成。在Juno项目中,我们花了几个月的时间一度重新设计:只是移动东西,清理它们,创建有意义的基类,并在模块之间创建清晰的接口。但是我们用现有的代码库仔细地做了这件事,并且我们没有引入新的bug或丢弃工作代码。

程序员认为他们的代码一团糟的第二个原因是效率低下。有传言称,Netscape中的渲染代码速度很慢。但这只会影响项目的一小部分,您可以对其进行优化甚至重写。你不必重写整件事。在对速度进行优化时,1%的工作可以为您带来99%的收益。

第三,代码可能非常难看。我参与的一个项目实际上有一种称为FuckedString的数据类型。另一个项目开始时使用成员变量以下划线开头的约定,但后来切换到更标准的“m_”。因此,一半的函数以“_”开头,另一半以“m_”开头,这看起来很难看。坦率地说,在Emacs中使用宏可以在5分钟内解决这类问题,而不是从头开始。

重要的是要记住,当你白手起家时,绝对没有理由相信你会比第一次做得更好。首先,您甚至可能没有开发版本1的相同编程团队,因此您实际上并没有“更多的经验”。您只会再次犯大多数旧错误,并引入一些原始版本中没有的新问题。

当应用于大规模商业应用时,要扔掉的旧咒语Build One是危险的。如果您正在试验性地编写代码,那么当您想到更好的算法时,可能会想要撕毁您上周编写的函数。那没问题。您可能希望重构一个类以使其更易于使用。这也很好。但扔掉整个程序是危险的愚蠢行为,如果网景真的有一些具有软件行业经验的成年人监督,他们可能就不会这么自食其果了。