注释是什么
注释是否有用一直以来都被程序员们广泛争论。也有人说,良好的编程习惯从写注释开始;有的人说,注释是恶魔,它将我们的代码变得很难理解。那什么才是注释?
注释就是对代码的解释和说明,其目的是让人们能够更加轻松地了解代码。注释是编写程序时,写程序的人给一个语句、程序段、函数等的解释或提示,能提高程序代码的可读性。 – 百度百科
注释主要是给人看的,其目的是增加代码的可读性。不同的公司、项目,对代码注释要求不同,他们被写入到编程规范中。而大多的规范中对注释关注的是格式,却难以说明如何正确地写注释,什么样的注释不应该写,什么地方需要写注释。
注释必要性
写注释与维护注释需要花费大量的时间,甚至比写代码与维护代码更花时间,大多的程序员都不喜欢写注释。即使在编程规范要求下,为了注释而注释,这种不情愿的做法导致形成了某种主义:注释是恶魔,认为代码注释实际上是有害的。大家都想逃避注释时,大多会举起这种主义大旗来反对。虽然代码注释有时候确实会适得其反,但真正有害的是我们对它的看法。
确实在一段晦涩难懂的代码中有一段合理有效的注释,会比仅仅有代码好很多。也有人要说,我们应该去重构晦涩难懂的代码,直到让代码能够自解释,让人非常容易理解,也就不需要注释了。我们通过有意义的变量名,自解释的方法、类名称,清晰的代码结构,能大大提升代码可读性。清晰的实现让我们产生一种错觉,认为不需要再写注释了。
的确好的代码能正确地反映代码正在做什么,但它却无法说明为什么这样做的背景、原因等。理想很丰满,现实却很骨感,完全自解释的代码是不存在的。过了几个月之后,当我们自己回头再看我们写的代码,有时候却难以理解为什么要这么实现。不要过于相信自己的理解力,因为当你写代码时,可能是思路清晰的;当你阅读代码,可能没有了当时的思路。
任何一个稍大点的软件系统,需要多人协作一起完成。一个人写的代码,需要被整个团队的其他人所理解。合理的注释会增强团队之间的沟通,尤其是对于接口类代码,是非常有必要通过注释来明确接口的行为,接口的用法。注释不是为了要指出代码中存在的缺陷,而是为了避免可能由于不恰当的使用导致的缺陷。
注释与文档
有一种观点,代码即文档。我们不能望文生义,注释提升了代码的可读性,但它并不能代替全部的文档。每一种编程语言,都有自己的注释格式规范,基于特定的标签,通过工具能自动生成格式化的文档。
对外提供的API,通过注释文档化是非常有必要的,我们把这类叫API文档。这类注释文档好处是,开发代码的同时开发文档,保持一致性。
生成的文档能清晰地说明每个类、方法的作用与用法。但他们通常是片段式,缺少整体连贯性。虽不说注释能代替架构设计类文档,即使使用指导或开发指导都无法代替。
怎么写注释
现在,我们不难发现:注释是必要的,只是注释不应该记录代码在做什么,而是记录为什么要这么做以及怎样做。
大部分代码不是SDK之类的代码,而是业务逻辑代码。大部分情况下不需要、也不应该注释。尤其是业务类的代码,当需求改变了,代码也随之跟着变化。如果我们写注释,这就意味着必须去维护注释。如果注释没有跟随代码的变化而变化,那终将是无用的注释。所以:
- 不必要对每行代码都写注释
- 不必要对每个函数都写注释
- 不要写直接代码翻译的注释
- 不要写没有额外含义的注释
- 不要写代码是谁写的,SCM有提交记录
有必要的注释是:
-
描述解决的问题
注释将代码做的事情用语言再描述一遍,其实是画蛇添足。后续维护者或者代码阅读者,最想知道的是为什么这么做,是为了解决什么特殊问题吗?有没有什么复杂的业务背景。
-
描述场景的约束
任何一段代码,有它的输入输出。不同的前置条件,会有不同的结果。在什么场景下使用,使用后会产生什么样的后果。当代码本身无法表达它的约束时,需要通过注释额外地说明使用场景,系统约束。
-
描述关键算法实现
当代码涉及到算法实现时,由于可能会使用到数学公式,公式到代码的实现通常是比较以及理解的。这类的代码我们应该描述使用了什么算法,算法实现可参考的论文地址等。
-
描述代码实现思路
有时我们写代码会考虑比较深远,但现有代码并不会完全实现将来可能发生的情况。针对他们可能已有明确的实现思路,为了代码的连续性,我们有必要说明后续可能的变化,在现有代码如何地修改,从而避免后续维护者破坏性的修改。
结语
代码自解释不代表不用写注释,也不存在能完全自斛释的代码。没有人喜欢糟糕的注释,也不应由于注释会过时成为偷懒的借口。排斥注释并不能解决注释本身质量的问题。合理有效的注释是代码一部分,站在维护者角色来思考如何写好必要的注释,将会有不少的收益。