翻译 | 注释在代码维护中的重要性

2019-09-081978

原文自国外技术社区dzone,作者为 Brian Hannaway,传送门

我一直是一个崇拜注释的人,对我来说,这不是一个脑筋活,而是一件有意义的事情,并且对于为了更好地构建易懂易维护的软件中是尤其基础的一部分。虽然并不是每个人都认同这个观点,有部分人说,注释并不是必要的而且对于并不是非常重要的代码来说注释就像多此一举。在这篇文章中,我会尝试去怼这些言论并且告诉读者你们为什么我会认为有质量的注释是可维护软件中的重要组成。

帮助别人看懂你的代码

作为一名开发者,我们会花费相当长的一段时间去阅读和尝试去了解别人的代码。有时候这会演变成一件艰巨的任务。我们的大多数人都遇到过同样的窘境, 在零文档的"前人坑"代码中费劲心思 — 没有任何单元测试、没有任何注释。写着玩意儿的老哥可能已经不在了,并且留到我们这边去思考这"该死的"玩意应该怎么处理。可想而知,这一点也不有趣,难道不是吗?

这份经验应当提醒我们,作为一名开发者我们有责任去做实现功能外的事情并且尽量将代码写得易读,易理解和易维护。一个易读的代码库,对未来的开发以及以后接手你的任务的人来说都很有帮助。它可以让不同技术水平及不同技术领域的开发者都能理解你的代码并且减轻他们的工作负担从而提高开发效率。

注释 — 仅仅是拼图中的一部分

想要完成一副完整的拼图,来拼凑一个可维护的系统是需要数个重要的拼块的。基于我的个人经验,我罗列出一下几项。

  • 好的架构 — 单一责任的类设计,一个方法只做一件事情
  • 易读的命名 — 类、方法和参数应该有一个清晰的、易读的命名
  • 单元测试包围 — 单元测试描述一个组件应有的行为。除了测试预期的行为外,它也表现了组件的规范
  • 注释 — 比起代码,注释更能表现出重要信息

你也许会惊讶为什么注释在这几点的最后。但这不影响注释的重要性,而这更能体现出它跟其他点的不同。开发者应该始终强调去编写易读的、具有良好结构的代码。注释就像锦上添花,为阅读源码的人提供那些在代码中不能表达的思想。

##想想那些看你代码的人

在系统的整个生命周期,具有不同层级技术、经验和领域知识的开发者会一起工作来开发代码。在一个方面,你们可能拥有非常有经验的技术领头人或者架构师;而在另一方面,你们可能也有刚从大学毕业的开发人员。但关键是,你永远不会知道将来是谁或者什么级别的人去对接你的代码。基于这一点,你应该编写你的注释让对尽可能多的人都管用。如果你是一个具有丰富领域知识的技术主管,那么你不应该把注释写得以为之后的人懂得和你一样多。相反,在写的过程中始终需要谨记他们都可能是经验不足的人。

你可能会认为,尤其对于有经验的开发者来说,编写注释的风险太明显了。虽然这确实是个风险,但更重要的是,当我们将一个注释视作显而易见的时候,其实我们是在一个主观的状态下。对于具有15年工作经验的技术领头人来说,一些明显的东西对于初级工程师可能就是非常难懂了。

是什么以及为什么

当其他开发者在查看你们的代码的时候,这里有两件事情你是想让他们了解的。那就是这些代码是做什么的为什么要这样做。让我们仔细看一看。

解释是什么的注释

编写良好的代码在许多情况下是用来做自我记录。你的目标应该是使你的代码变得更让人印象深刻,从而减少那些用来描述你的代码做什么的注释。然而,有时候这种描述性质的注解也是非常有用的。

  • 当业务逻辑已经复杂到需要使用注释来描述你的代码的时候。是的,你还是希望使你的代码尽可能变得能够自我描述,但注释能够通过描述你想要实现的目标来增加价值。众所周知,代码所做的以及代码表达的意义往往不是两个相同的东西。
  • 有些代码完全没法表达任何意义。以正则表达式为例,是的,或许你可以为这个表达式添加一个描述性名称但是这不能帮助到读者去理解表达式的意义。在这种情况下,描述表达式和提供一个符合的例子的注释是非常有用的。复杂的 SQL 是另外一个例子,它不具有很强的表达力。一些简单的注释可以通过描述执行的意义来帮助指导读者理解。
  • 领域的概念是很难描述的。这听起来很容易理解,但是将事物命名得很好是非常棘手的,尤其对于一些复杂的领域。我花了很长的一段时间去研究忍受保险和退休金。有时我会发现很难用简单的名称来描述类、函数或者变量的用途。在这些情况下,我会提出那些最具有描述性的名称,然后添加简单的单词注释去描述它们业务术语的意义。

解释为什么的注解

解释为什么用这些代码的注释也是非常重要的因为这个信息无法从代码中获得。以下是一些重要的例子来描述你选择这样做的原因

  • 设计决策 — 解释你做出设计决策的原因的解释非常重要,特别是如果你已经实现一些类型的模式,并且也希望其他开发者在未来也会使用到的时候。指引手能够通过向需要指导的人展示扩展现有功能的最有效方法,能够帮助他们指出正确的方向。明确为什么你要做这件事同样可以减少未来某个人重构你的代码的可能性,以及减少无意中破坏你已经实现的模式的可能性。
  • 解决方法 — 我们有时必须解决由外部因素引起的那些我们很难或者根本没法控制的问题。也许从外部系统接收的数据在某些情况下需要进行调整才能运行。这样的解决方法虽然不现实,但是确实是企业发展需要解决的问题,特别是涉及到残留的系统的时候。注释能够通过解释根本上的问题以及为什么我们需要解决它来帮助到组织。注释为其他开发者提供事情的上下文并且减少某些人因为不理解而删除方法的可能性。
  • 边缘情况 — 有时我们会编写需要处理特殊边缘情况的逻辑代码。这些场景通常不直观,这时候就是注释出现的场景了。处理奇怪的逻辑通常比看起来它所需要的复杂得多。而注释是解释边缘情况的好方法,也是你实现的解决方法的原因。

通俗的注释

我尽量使我的注释变得非正式和通俗的。想象下你的一个团队队员坐在你旁边并且你在解释你部分的代码是如何工作的。你可以用简单的术语来解释,让你的队员能够尽可能地理解。我认为注释也应该以相同的方式,通过简单的表达来回答问题。请记住,注释能够提供那些代码不能提供的信息,所以尽量使它们变得能够让别人接收的形式。

质量胜于数量

像生活中大大部分例子,注释应该强调质量而非数量。应该仔细、细心地使用注释,告诉读者一些代码无法轻易表达的内容。可以说,带有大量有用的注释的结构化、易读的代码,比起用大量注释来解释每行代码作用的糟糕的代码要好的多得多。

避免多余的注释,能够更清晰的描述代码的作用。注释和代码一样,需要不断去维护。避免多余的注解能够具减少维护开销,并且能够帮助读者关注那些重要的注解。

避免注释腐朽

注释腐朽是指当代码更新的时候但附带的注释没更新。这会导致注释过时并且与他们对应的代码是相矛盾的。注释腐朽经常被认为是代码注释的一个重要的缺点,但我认为这个观点有效性很低。虽然我同意注释腐朽是一件不好的事并且有些事情是需要避免的,但是这并不是一个完美的理由去停止对你的代码进行注释。最好的防止注释腐朽的方法是显而易见的。。。当更新代码的时候更新你的注释。和大多数好的实践一样,这需要以代码审核的形式,结合开发人员的纪律性来治理。

包装起来

注释并不能代替结构良好、易读的代码,但是它们能通过表达那些代码不能表达的信息来帮助开发者们。更容易阅读、理解和维护的代码最终转化成更高的生产力和更多的模块被创造出来。我敢打赌这也能够使你的 boss 感到愉悦吧。

分享
点赞1
打赏
上一篇:Docker常用命令笔记(一)
下一篇:翻译 | 关于 System.gc() 你需要知道的一切