Osheep

时光不回头,当下最重要。

以完美主义的名义,拖延症在公开掠夺

《以完美主义的名义,拖延症在公开掠夺》

简评:一个系统的迭代开发可以持续几年甚至更久,而某行代码的生命周期则短很多,一次到位的开发不现实也没有必要。代码的正确性、安全性比美观更重要,不要将时间浪费到编写完美代码上。

不同代码重要性的优先级不同

Michael Feathers 在研究代码随时间发生的变化中,发现了代码的生命线。

通常,每个系统都有许多一次写成就几乎不再修改的代码。但是依然有一小部分代码,包括最重要最有用的代码,会被经常修改,重构甚至重写数次。

随着开发者对一个系统、一类问题或者一个架构方案的深入了解,应该能够更加轻易地知道或者预测到哪些代码会不停改动,哪些代码几乎永远不变。换句话说,有的代码比其他代码更重要。

是否应该努力去写完美代码?

从第一个 hello world 开始,我们就知道应该努力写简洁的代码,保持代码的一致性和易读性。于是一些强迫症患者的程序员便开始痴迷于优雅完美的代码,每时每刻都在斟酌重构代码的每一个细节。

有的代码只需要写一次,以后就再也不需要作任何变动,但有些代码并非如此。试想,这些需要不断改变的代码,代码写得那么完美却在下一秒立马就被 delete 岂不是太过浪费?而且也没有必要这么做。

You Can’t Write Perfect Software. Did that hurt? It shouldn’t. Accept it as an axiom of life. Embrace it. Celebrate it. Because perfect software doesn’t exist. No one in the brief history of computing has ever written a piece of perfect software. It’s unlikely that you’ll be the first. And unless you accept this as a fact, you’ll end up wasting time and energy chasing an impossible dream.” — Andrew Hunt, The Pragmatic Programmer: from Journeyman to Master

只写一次的代码首要并非美观或优雅,而是正确性和易读性。因为在整个系统的生命周期中,它们虽然不再修改,但是可能需要被阅读很多次。不一定非要紧凑,干净即可。

在这些代码中,一定程度上的拷贝和粘贴等操作也是可以接受的。它们不需要反复斟酌,除非你需要修改它,否则即使周围代码都在变,也不需要对这些代码重构。对于这些代码,没必要花费过多时间。

至于那些频繁修改的代码,苦苦思索最优雅的方案更是在浪费时间,本来它们就可能在几天后被修改或重写。同样,每次修改都痴迷于代码的重构,或者重构那些不需要修改的代码试图使其变得更好也是没有必要的。

代码永远都可以变得更好,但这永远不是最重要的方面。我们关注的重点应该是 —— 这些代码是否实现了所需功能?能否正确高效地运行?能否处理异常数据而不崩溃?即使异常,调试时是否方便?所有这些和美观优雅无关的地方,才更应该是代码质量优劣的衡量标准。

务实地进行编码和重构

精益开发的核心思想是:不要把时间浪费到不重要的事情上。应该用这个原则指导我们如何编写代码,如何重构代码,如何进行代码审查以及如何进行代码测试。

为了完成工作,只进行必要的代码重构,Martin Fowler 称之为机会主义重构和有预备的重构。这足以使代码修改起来更加简单和安全。如果你不是在修改代码,代码看起来是什么样其实无关紧要。

在代码审查中只关注真正重要的部分,这些代码是否正确?是否是防御性的代码?是否安全?你能否理解它的思路?修改起来是否安全?

不要纠结于代码的风格(除非代码风格误导了你对代码的理解),把格式化代码的工作交给 IDE。没有必要去争论这些代码能否“更加面向对象”。只要它有道理,至于是使用这用模式还是别的模式,并不重要。同样,至于你是否喜欢,也不重要,尽管你可以用更好的方式完成它,除非你是在教对平台或者语言不熟悉的新手,需要在代码审查中完成监督工作。

测试用例的编写很重要,需要覆盖到主要的执行路径和重要的异常情况。测试用例能够用最少的工作量给你尽可能多的信息和信心,具体是采用大而全的测试还是小而精的测试则无关紧要。至于是在写代码之前写测试用例还是在写代码之后写测试用例也不重要,只要测试用例有效即可。

不仅仅是关于代码

在软件领域里,建筑师和工程师的概念从来都不适用,我们不是设计建造屹立数年或者数百年大桥或者摩天大楼,我们构建的是更加具有可塑性的、更加抽象的,同时生命周期也更加短暂的东西。软件之所以称为“软件”,就是因为编写代码是为了修改。

After five years of use and modification, the source for a successful software program is often completely unrecognizable from its original form, while a successful building after five years is virtually untouched.— Kevin Tate, Sustainable Software Development

迭代开发教会我们不断尝试并检查尝试的结果 —— 是否解决了问题,如果没有解决问题,如何去改进?

我们正在构建的软件是永远做不完的。尽管设计和编码是正确的,那也可能只是一时正确,一旦需求发生变化,就会被更加适合的设计和编码替代。

我们需要写好的代码:易懂,能够正确运行,有安全保障的代码。我们需要对它进行重构和代码审查,并且编写有效的测试用例。但是要记住,其中的一些代码或者全部代码可能很快就被丢掉,甚至再也不会被用到。我们需要意识到,我们的一部分工作可能要被浪费掉并且对此进行优化。

只做哪些需要被完成的事情,不要浪费时间试图去编写完美代码。

原文链接:Don’t Waste Time Writing Perfect Code
“本译文仅供个人研习之用,谢绝任何转载及用于任何商业用途。本译文所涉法律后果均由本人承担。本人同意简书平台在接获有关著作权人的通知后,删除文章。”
推荐阅读:
Github | 程序员七大生产力工具
程序员常犯的五个非技术性错误

点赞