传统的印象里,良好的代码都是需要丰富的注释的。看完《代码整洁之道》注释这章之后,发现根本不是这个样子:
什么也比不上放置良好的注释有用。什么也不会比乱七八糟的注释更有本事搞乱一个模块。 什么也不会比陈旧的、提供错误信息的注释更有破坏性。
注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败。注释总是一种失败,我们无法找到不用注释就能表达自我的方法,所以不得不用注释,这并不值得庆贺。
注释存在的时间越久,就离其所描述的代码越远,越来越变得完全错误。原因很简单 ,程序员不能坚持维护注释。
所以,尽管有时也需要注释,我们也该多花心思尽量减少注释。
一、注释不能美化糟糕的代码
写注释的常见动机之一是糟糕代码的存在。我们编写一个模块,发现它令人困扰、乱七八糟。我们就知道,它烂透了。我们告诉自己:“好写点注释”。
其实不应该这样,我们好应该把代码弄干净。
带有少量注释的整洁而有表达力的代码,要比带有大量注释的零碎而复杂的代码像样的多。
二、用代码来阐述
有时,代码本身不足以解释其行为。不幸的是,多数情况下,很多程序员都因此认为代码不能做好解释工作。这种观点是错误的。比如如下两段代码,你更愿意看到哪种?
不好的实践:
// Check to see if the employee is eligable for full benifits
if ((employee.flags & Hours_FLAG) && (employee.age > 65)) {
}
良好的实践应该类似这样:
if (employee.isEligableForFullBenifits()) {
}
尽全力把代码写的简洁明了,再用注释解释。很多时候,简单到只需要创建一个描述与注释所言同一事物的函数即可。
三、好注释
有些注释是必须的,也是有利的。下面会介绍一些值得写的注释。不过要记住,真正好的注释是你想办法不去写的注释。
1).法律信息(版权等等)
2).提供信息的注释
3).对意图的解释
4).阐释晦涩难懂的参数、返回值的意义
有时,注释把某些晦涩难明的参数或返回值的意义翻译成为某种可读形式,也会是有用的。通常,更好的做法是尽量让参数或者返回值自身就足够清楚。但如果参数或者返回值是某个标准库的一部分,或者是你不能修改的代码,阐释型注释就很有意义了。比如:
5).警示
有时,用于警告其他程序员会出现某种后果的注释也是有用的。比如,protocol buffer编译器根据.proto文件自动生成的代码,是强烈禁止被程序员自己修改的:
6).定期清理TODO注释
有时,有理由在代码中放置未来的工作列表。此时可以用//TODO。
TODO可以代码在未来的功能或发展目标。
但是要注意定期查看TODO(借助现代IDE定位),删除过时的TODO注释
7).公共API中的javadoc
四、坏注释
1).喃喃自语(注释是给读者看得不是给自己看得)
大多数注释都是此类,通常坏注释都是糟糕代码的支撑或接口,或者对错误决策的修正,基本上等同于程序员自说自话。
2).多余的注释(没有提够比程序本身更多的信息)
很多余。。。
3).误导性注释
注释描述的功能和实际函数的功能有出入
4).循规式注释
所谓每个函数都要有javadoc或者每个变量都要有注释的规矩完全是可笑的。 我的理解是给函数或者变量起个好名字吧。
5).日志式注释
在没有源码版本控制系统时,可以这么写。
如今,这种冗长的记录只会让模块变得凌乱不堪,应当全部删除。
6).废话注释
无参构造器你都要来个注释?服辣
7).标记位置 (例如://看这里///)
// Actions /////////////////////////////
有时,程序员喜欢在源代码中标记某个特殊位置。
尽量少用,只在特别有价值的地方用。如果滥用标记,那么标记就会不突出,沉没在海量的标记中,失去标记价值。
8).括号后边的注释
9).归属名
源码版本控制系统会帮我们记录,没必要自己添加签名注释。
10).注释掉的代码
注释掉的代码,其他人不敢删除,因为不清楚有没有用。注释掉的代码不及时清理,堆积成山后,很难看。
11).HTML注释(这里是指在注释中添加HTML标签,扰乱视线)
12).非本地信息(就是说你在注释中描写另一个代码块)
如果你确实需要注释,请确保它描述了离它近的代码。
13).信息过多
别在注释中添加有趣的历史性话题或者无关的细节描述。
14).不明显的联系(也就是说要写就写清楚)
这里面过滤字节是什么?与+1有关系么?与*3有关系么?为什么用200?完全没有说清楚。
如果注释本身还需要注释来讲明白,那太遗憾了。
15).函数头
一个好的函数名远远好于一个注释
16).非公共代码中的javadoc
虽然Javadoc对于公共API非常有用,但是对于不打算作公共用途的代码就令人厌恶了。为系统中的类和函数生成javadoc页并非总有用。
参考
《代码整洁之道》