对重写代码说不。
以下为译文:
1、重写代码消耗了12个月!
我们从头开始重写代码浪费的时间。
你能想象在软件行业,12个月的时间没有任何新产品推出,没有任何新版本更新吗?
真的,我不由自主地问自己这个问题:
在这个快速发展的世界里,12月的时间能让我们做多少事情?
“2015年1月20日,星期二,下午5:10,AntiMalware软件终于进入了第一次公测。”
经过几十个小时的不眠不休后,第一个版本的软件说明书终于发布到了网站上,这标志着我们的新旅程的开始。
我在一家为企业和终端用户提供安全软件的小型网络安全公司工作。我们开发的软件保护用户免受恶意软件的侵害。如果用户的电脑被恶意软件感染,我们的软件会帮助他们清理。AntiMalware就是其中一个软件。
第一个测试版收到的反馈令人鼓舞。我们有四个开发人员为这个产品工作,不断地修复Bug, 改进产品功能,推出新版本。
2、第一个稳定版本
经过两个月的纠错、功能改进和编码工作,我们发布了AntiMalware的第一个稳定版本。
看看用户怎么说?
大多数用户的反馈都很好,他们喜欢这个产品。这让我们的团队深受鼓舞,大家卯足了劲地干活,来改进这个产品的核心功能。
3、进入市场
2016—2017。
大风暴来临前的黄金岁月。
AntiMalware软件处于它的最佳期,它成为了我们的旗舰产品。用户纷纷把它推荐给他们的朋友们。所有与安全相关的博客和论坛也都在推荐这个软件。它成了拯救被恶意软件感染的用户的首选软件。
下载、安装、销售,一切都向好的方向发展,用户群在几个月内迅速增长。 创始人很高兴,团队也是如此。大家都在想:“我们做到了! 像其他大公司一样,我们认为我们创造了自己的成功故事。“
4、新机遇(至少我们这样认为):进入企业市场
后来,公司决定进入企业市场。一个新的企业产品团队成立了。原产品负责人离开了公司,我们的CTO接任成为新的产品负责人(这是灾难的开始,稍后我会解释)。
一些开发人员离开了公司,但没有什么影响。我们把每件事情处理得很好,AntiMalware软件仍然是市场上最好的选择。
5、好日子结束, 麻烦开始
正如我前面所说,我们的CTO成了AntiMalware的产品负责人,他需要处理AntiMalware的方方面面。而且他还是该软件的首席开发人员,负责不间断地发布更新和功能提升。同时,他的职位让他还需要处理公司的其他事务。
当然,一开始都很顺利,我们的情况就像所有软件开发一样,我们不间断地维护和改进我们的软件。
正如我们应该预料到的(显然我们没有),不知何故,软件开发过程开始慢下来。
新的版本更新开始延期了,这种情况持续了一阵子,很快就变成没有版本更新了。这让我很不安,有一天我问CTO:
“这个产品出了什么问题?为什么版本更新要花费那么多时间而且开发进展缓慢?”
他深吸一口气,开始回答:
“我们的代码太复杂,它的结构不好,耦合太紧。架构设计完全错误,用户界面和核心逻辑代码混杂在一起,每当修复一个Bug或作某些改变时,其他部分就会受影响。即使是小的改变也很难做好。每次更新,都会引起新的问题。
一些方法竟然有20个参数,方法体的代码有两页长!你能想象吗?有许多不应该实现的东西不知为何都实现了。
这就是为什么每次更新都要花费很长时间而我们无法推出新功能的原因。每次我们推出一个新版本,我都担心可能会引入新的Bug,而那些现在工作得很好的核心功能则有可能因此无法工作。在这种情况下,发布新版本太冒险了,我们可能会失去我们的用户,我们的软件无人再愿意使用。”
他的回答中提到的一系列问题其实我们都知道。只是,我们期望从他的口中说出来。
我还问了一个问题。负责这个软件的前任首席开发人员为这个软件开发了一年时间,而他都在CTO的管理下,那么CTO为什么允许这样混乱的代码出来呢?
“我不想打击他的积极性,我们必须尽快进入反恶意软件市场,他很擅长这个,所以我才没有制止他这样做。”
CTO这样回答。
也就是说,为了以最快的速度进入市场,我们牺牲了代码质量,这样做也等于破坏了这个产品的未来。
经验教训:
要在第一时间对不好的代码设计说“不”,不要让“面条式代码”毁了你的产品的未来。要确保做出的软件产品有可持续开发性。
6、那么,如何修复这个可怕的代码?
“我们都是程序员,而程序员的心中都驻着个建筑师,当他们到达一个地方的时候,他们想做的第一件事就是把这个地方夷为平地,然后在上面建造一些宏伟的建筑。我们对那些渐进式的更新不感兴趣:如小修小补、改进、种种花草等等。”
-?Joel Spolsky,Stackoverflow公司CEO
开发人员总是倾向于抛弃旧代码然后从头开始,他们有这样做的理由。因为他们认为旧代码都是无用而且凌乱的。但是这只是想当然的理由。当我们试图找出背后的真正原因时,我们会发现:
我们可能错了!
旧代码对我们来说可能看起来很凌乱,必须从头重写的原因并不是因为代码本身,而是因为一个重要的,基本的编程法则:
读代码比写代码难。
这解释了代码重用困难的原因,也解释了为什么我们认为旧代码象头发一样凌乱。因为这个原因,当我们阅读另一个开发人员的代码时,我们的潜意识会不断对着我们耳语“扔掉它,重新开始”。
像所有开发人员一样,我们也落入了这个陷阱。只是读一遍我们的凌乱的代码就足够让我们下决心考虑从头重写了。
在一系列的会议之后,即使CTO对重写代码有抵触(他是对的),他最终还是被说服了,我们决定从头重写代码。
然而,重写代码的决定并没有持续太久…
那是一个周末,星期日,我边喝早茶边读一些推送文章。就像我的推送知道该向我展示什么一样,我读到了那篇最著名的关于重写代码的文章,就是Joel Spolsky写的Netscape 的代码重写故事(https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/)。
读完那篇文章后,我立马分享给了AntiMalware开发团队,包括CTO。
然后我们开始了新的讨论。
本来说服CTO作出代码重写的决定就已经很难了。他在读完那篇文章后马上改变了主意,他决定中止代码重写。这让其他团队成员生气了,他们冲我大喊大叫:
“你为什么给他看那篇文章?我们都已经说服他了。这个产品必须从头重写,这是唯一的解决方案。”
我们的第一次重写代码的尝试到此结束了。关于这个话题的讨论也终止了。我们的CTO相信我们可以管理好这个糟糕的代码,并有能力在它之上发布新版本,直到严酷的现实击倒我们为止。
一年没有任何更新…
真的,这不是玩笑。真的一年没有更新了!
“为什么没有更新?“
“自上次更新到现在已经有好几个月过去了。”
每天,我们都得面对这些来自用户的负面评论。作为一家小公司,我们需要管理的产品太多了,而且,我们又进入了企业市场,这些加在一起,使得我们陷入了这样的困境。
把所有这些结合起来,你就会得出这样的结论:我们忘记了我们的用户。
回想一下,我们不想发布新的版本,因为我们不想失去用户。
但事实应该是相反的:如果我们不发布新的更新,我们肯定会失去用户,而我们已经一年半没有给他们任何新版本了。
在被现实打了一巴掌之后,我们决定回头。对我们来