反思:那些你不该做的事情

最近在重新看 Joel on Software 的blog,时隔二十年,很多错误还在重复发生,很有感触,比如这篇,翻译过来,引以为戒。

网景发生了什么?

网景6.0终于要进入第一个公开测试版了。实际上,从来没有5.0版本。上一个主要发布版本4.0已经发布了将近三年。在互联网世界,三年是相当长的时间。在此期间,网景无助地坐视其市场份额大幅下降。批评网景发布版本之间的等待时间如此之长似乎有点伪善。他们不是有意这么做的,对吧?其实是的。他们犯下了任何软件公司都会犯的最糟糕的战略错误:他们决定从头开始重写代码

程序员在想什么?

程序员的内心是建筑师,当他们到达一个地方时,首先想做的事情就是将其铲平,建造一些宏伟的东西。程序员对逐步翻新、改进和种花园不感兴趣。程序员总是想要扔掉代码重新开始有一个微妙的原因。原因是他们认为旧的代码很糟糕。这里有一个有趣的观察:他们可能是错的。他们认为旧代码很糟糕的原因是基于程序设计的一个基本法则:
阅读代码比编写代码更困难。
这就是为什么代码再利用非常困难的原因。这就是为什么你团队中的每个人都喜欢用不同的函数将字符串分割成字符串数组。他们编写自己的函数,因为这比弄清楚旧函数如何工作更容易、更有趣。

这样做的问题是什么?

新代码比旧代码更好这种想法显然是荒谬的。旧代码已经被使用过了。它已经经过了测试。已经发现了许多错误,并对其进行了修复。它没有任何问题。它不会只是因为闲置在你的硬盘上而产生错误。恰恰相反,它会变得更加完善!
比如,一个程序员在分析旧代码时会说:“看一下这个函数,它有两页长!里面的这些东西都不应该放在这里!我不知道这些API调用的一半是干什么用的。“
这个API只是一个简单的用来显示窗口的函数,但它变得越来越复杂,无人知晓。其实,原因是:那些复杂的代码都是为了修复bug。一个修复了Nancy在试图在没有安装Internet Explorer的电脑上安装应用时遇到的问题。另一个修复了在低内存情况下出现的bug。还有一个修复了当这个文件在软盘上且用户在重要时刻拔出软盘时出现的bug。而那个丑陋的LoadLibrary调用,却可以让代码在旧版本的Windows 95上正常运行。
每一个bug都需要经过几周的现实世界使用才能被发现。程序员可能花了几天时间在实验室里重现bug并修复它。如果像很多bug一样,修复可能只需一行代码,甚至可能只需要几个字符,但这几个字符需要付出大量的工作和时间。
当你丢弃代码并从头开始时,你也在丢失所有那些知识、所有那些收集到的bug修复,以及多年的编程工作

正确的做法是什么?

当程序员说他们的代码一团糟时(他们总是这么说),代码可能存在三方面问题。
首先,存在架构问题。代码的分配不正确。网络代码突然跳出自己的对话框,这些应该由UI代码处理。这些问题可以逐一解决,通过仔细地移动代码、重构、更改接口。这可以由一个程序员仔细地工作,并一次性检查他的改变,以便不会干扰其他人。即使在不丢弃现有代码的情况下,也可以进行相当大规模的架构变更。在Juno项目中,我们曾经花了几个月时间进行重新架构:只是移动代码、清理它们、创建有意义的基类,并在模块之间创建尖锐的接口。但我们以现有的代码库仔细进行,没有引入新的bug或扔掉正在工作的代码。
第二个原因是代码效率低下。据说,Netscape的渲染代码很慢。但这只影响了项目的一小部分,您可以进行优化甚至重写它。您不必重写整个项目。优化速度时,1%的工作可以让您获得99%的成果。
第三,代码可能很丑陋。我曾经参与的某个项目实际上有一种叫做FuckedString的数据类型。另一个项目开始时使用了以下划线开头的成员变量命名规则,但后来转为更标准的“m_”。因此,一半的函数以“”开头,另一半以“m”开头,看起来很丑。老实说,这种问题可以在Emacs中使用宏几分钟内解决,而不是从头开始。

总结

重要的是要记住,当你从头开始时,没有任何理由相信你会比第一次做得更好。你可能没有与原版本一起工作的相同编程团队,因此您实际上没有“更多经验”。您只会再次犯许多旧的错误,并引入一些原版本中没有的新问题。

请我喝杯咖啡吧~

支付宝
微信