坎德人的小包包

欧剃,游荡的坎德人,在他的旅途中收集了许许多多有趣的东西。

发表日期:2019-03-24

别追求完美的代码了,这7个关键点你搞清楚没有?

—— 抛弃你膨胀的自尊吧,对用户来说,程序里面的代码优美不优美,牛逼不牛逼完全无关紧要,真正重要的是程序运行起来是不是符合预期,是不是能满足用户的需求。随着时间...

作者:Aussie Tech Tutor


不管什么时代,做人做事,都贵在有始有终。对计算机程序而言,事情也差不多。一个好的程序,对于各种不同的输入,都应该返回可预期的输出。对用户来说,程序里面的代码优美不优美,牛逼不牛逼完全无关紧要,真正重要的是程序运行起来是不是符合预期,是不是能满足用户的需求。作为一个程序员,我深深地理解这种观点。随着时间的推移,我越来越领悟到,代码是不是很完美跟程序最后能不能完成任务相比,其实真的不怎么重要。

真正重要的是什么?

显然,作为开发人员,我们总会在保持代码库的整洁方面花上很多时间和精力。我们采用各种设计模式,使用我们最好的面向对象(OOP)实践,讨论和实现架构等。这些做法都非常棒,如果你可以一直采用这些最优的做法,那么显然应该继续保持下去。

但随着时间的推移,以及客户对快速交付的要求越来越明显,我个人开始把注意力从整理代码的内业工作中挪开,确保我能时刻专注于以下几点:

  1. 测试驱动开发 :我们是否能确保正在建设的产品满足预期要求?我们应该确保定期的自动化测试能够覆盖到整个系统,并根据当前正在构建的内容,将精力放在不同类型的测试上。

  2. 可扩展性:是否可以轻松快速地扩展现有软件以实现更多的功能?有时,过度的软件工程或过度的架构系统都可能会牺牲可扩展性。因此,必要的时候可以忽略架构和工程的要求。根据你项目的实际情况,你需要在二者间保持一种平衡。这是一个持续而且动态的过程。

  3. 自动部署:对系统的更改,我们是否能够快速部署?万一出现问题,是否能够回滚?

  4. 测量和反馈:我们是否能衡量系统运行的好坏?我们是否能跟踪用户的行为?分析非常重要。只有这样,我们才能决定如何改进。

  5. 错误管理:我们是否正确处理了任何未预期的错误?甚至,可预期的错误是否得到正确处理了?是否返回了正确的错误和错误消息?这些问题能不能被有效地追踪到(比如通过日志文件、控制面板等)?

  6. 性能:我们的代码是否针对性能进行了优化?如果不是,我们需要考虑重构,或是换种实现方式来改善代码性能。负载测试之类的方法可以帮助我们发现各种性能问题。

  7. 可伸缩性(Scalability),容错性/韧性(Resiliency)和持久性(Durability):系统是否能伸缩以在重负载的情况下可靠工作?如果出现严重错误,系统是否可以快速、可靠地恢复?我们希望确保我们的系统不会当机,如果实在遇到大麻烦,起码也不会长时间当机。

当然,以上几点并不能覆盖开发者需要考虑的所有事项,但我觉得,这是我们需要考虑的最重要的几件事。其中有些是我必须独自面对的,有些是我和我的团队必须共同战胜的挑战。不管具体处理问题的是谁,除非我们至少已经把精力集中在这些方面上了,否则我个人是不会对项目的状态感到满意的。

代码可读性不用管?

请注意,我没有代码可读性代码可维护性放在上面的列表中。为什么?如果你问大多数开发人员,他们会告诉你,这两个已经在他们认为最重要的3件事里了。我知道,因为我也早就习惯这样了。但是,当我开始从项目全局出发,而不仅仅是作为开发者的角度来看问题的时候,我就意识到,其实只有我们程序员自己会关心的代码可维护性和可读性。这是为了方便开发者自己,让我们的工作更轻松。

让我再说明白一些。具有高可读性和可维护的代码绝对是理想的。我不会质疑这一点。事实上,我确实建议在敏捷开发的冲刺(sprint)迭代过程中,花费时间重构一些代码库,以便在需要时降低复杂度。即使只花了半天时间,这也是值得的。但追求高可读性和高可维护性的问题在于,在开发过程中,你需要不断花时间提高代码质量,而这会严重阻碍项目进度。而只要我们解决了上面列出的 7 大块问题,对我来说这就已经足够了。

没错,如果你已经发现了代码中的一些问题,而且很容易进行修复,那就修复它。否则,应该先把它放在一边,标记为以后可以重构的东西,然后继续你的开发工作。我们需要保持整个开发流程的不断推进。在解决了我们必须关注的所有主要问题后,我们总能再回过头来进行重构。

代码风格有要求?

关于维护代码,我想说的另一件事是政治正确。也许有些人会对我不爽,但我不在乎。在我看来,强制要求代码风格往往会适得其反。特别是讨论你必须用空格还是 tab,或者是不是要在私有变量之前加上下划线等,那就完全是胡说八道了。我们又不是在 Windows 记事本里写代码,大部分都在用内置了智能感知功能的 IDE。在 IDE 的帮助下,你可以很快就区分出私有或公共的对象,静态和动态的对象,哪些是类而哪些不是类……等等等等。我们又不是把代码发到打印机,然后在纸上阅读它。因此,只要能够理解代码试图实现的目标,就不要管它。

抛弃你过分膨胀的自我吧。不要期望每个人都用和你一样的习惯工作。每个人都有不同的写代码方式,也永远不可能完全相同。你可以给出点简单的建议,比如“你考虑过这个吗?”,但是别在其他人身上强制执行你的概念和做法。是的,我不得不接受这个现实,而现在其他人也明白了。如果代码能有效工作,他们就完成了自己的任务,不管你是否喜欢他们的实现方式。

代码审查也不需要?

考虑到这一点,有些人可能会对我说,我肯定也不关心代码审查。

并不是这样的。我只是以不同的方式去理解这件事。

对我来说,代码审查应该是审阅者根据代码的内容(而不是风格),评估特定的 Pull Request 是否达到目标要求的功能,或者它是否会对程序中的某些其他功能产生负面影响。如果对代码在某些情况下应该如何处理存在疑问(比如错误处理不对,或者没有检查空值等),我们有机会与编写它的人进行讨论,听取意见,如果你仍然觉得这里存在问题,你可以让他们注意到它。如果你自己不确定某些东西为什么要这样做,你也可以进行团队讨论,明确应该要怎么做。此外,代码审查还使我们有时间评估,在进行了这次更改后,是否还能满足我之前提到的 7 大要点。

对我来说,代码审查并不是提出诸如变量命名格式等愚蠢的意见(除非变量的名称可能使别人产生误解)。那些代码风格狂魔真的很烦人,而且在大多数情况下,对这类话题每个人都会有不同的意见。所以,没必要关心这类事情。

结语

我的底线是,我同意拥有易于维护的代码当然是最理想的,但有的时候,把代码暂时搁置一边,并继续向前推进才是更好的选择。在考虑了上面这些方方面面之后,请记住,我们的总体目标是尽可能快地交付软件,并更加注重维护保证它的正常稳定运行,而不是关心它是如何构建的。专注于解决关键的 7 个问题,永远比代码的整体结构更重要得多。


欢迎大家踊跃留言,分享一下你遇到过的奇葩代码审查规范吧!

(本文已投稿给「优达学城」。 原作: Aussie Tech Tutor 编译:欧剃 转载请保留此信息)

编译来源: https://medium.com/design-and-tech-co/why-i-no-longer-care-about-perfectly-written-code-bedafa2110b

标签:UdacityTranslate

Powered by Jekyll on Github.io
2022 © 欧剃