生活程序员首页投稿(暂停使用,暂停投稿)

coding时尽量不要写注释

2015-09-16  本文已影响4515人  匿蟒
coding时尽量不要写注释

在学校里学习时,老师对注释的要求比较严苛。

你写代码的时候不写注释,过一段时间你自己都看不懂了,何况别人?

上一句还属于常规观点。某个老师甚至这么说:

C语言,注释量应该和代码量相当。

当时,我是心中敬仰的。然而,工作后发现,实际工程领域之中,并没有那么多注释。
而且,逐渐发现,大部分情况下不需要、也不应该注释

由于工作中以Java为主——这真是一个悲伤的故事——以下代码以Java为例。

1. 错误的注释不如没有

注释写出来,就是给人看的。如果注释是错的,就会误导代码阅读者。

/**
 * I am a boy, I like girls.
 *
 * @param someone is a Person who is welcome or not.
 *
 * @return true if someone is a Person you like.
 */
private boolean isWelcome(Person someone) {
  return someone.isBoy();
}

比如上面那段,代码是个同性恋写的,注释的则是异性恋;或者,当他写注释的时候以为自己性取向很正常,写代码的时候心中忽然涌上一阵明悟……

这类注释在实际工作中碰到很多。在维护代码、或者是在以前的基础上开发代码的过程中,往往是进行增量修改。某些时候,Method内的实现已经改了,而代码注释未变,就容易出现二者不一致,甚至意义完全相反。

修改代码时,一定要先修改相关注释。这就带来了维护成本的提高。

问题是:增加的维护成本以及误导几率,是否能被注释带来的收益所抵消?

2. 没有额外语意的注释不如不写

注释不仅要说明,还必须要有额外语意,或者更简单地表达了与代码实际效果相同的意思。

public class Person {
    /** The name of the Person. */
    private String name;
    /** The phone number of the Person. */
    private String phoneNumber;
}

上面那段,这样的注释,有什么意义?

这类为了注释而注释的注释,除了碍眼,并无意义。而且,还容易出现第1类问题。

比如,以后人类都不用注册、购买电话号码了,直接用身份证号作为联系方式。上面的代码需要把phoneNumber改为id,修改者会不会记得改注释?

他心中一定有一万头草泥马在狂奔:还不如删掉!

3. 必要的注释是代码的失败

其实,看代码的人都是码农……呃,我是指,看代码的人都是能看代码的人。一般不会存在没有注释就看不懂的代码。

注释只不过是加速理解代码的过程。

而且,看了注释,不代表就不需要看代码。因为有可能存在第1类问题。

/**
 * @return true if this is a girl and she is beautiful.
 */
public boolean isGood() {
    int value = this.getValue();

    // If the 1st bit of value is 0, means this is a girl.
    // If the 2nd bit of value is 0, means this person is beautiful.
    if ((value & 0x01) == 0 && (value & 0x02) == 0) {
        return true;
    } else {
        return false;
    }
}

以上代码中,Method的注释已经写得很清楚了,isGood()是看这个人是不是个美女。
这段注释的确加速了理解,因为isGood()并不是很直观。什么样的好才是好?

但是,为什么不把Method命名为isBeautifulGirl()?表达了同样意义的同时,也不用阅读者跳转到定义位置来看。

其次,在实现中的这段注释的确加速了理解,不然这个位操作要看很久(视脑年龄而定)。

但是,特么谁准你在Java里用位操作?!

不管你这个int里存了多少位的信息,为什么不能拆分成多个值?
如果拆分成多个值,每个值都给予恰当的命名,配以适当的Method,为什么还需要注释?

例如以下代码,需要注释吗?

public boolean isBeautifulGirl() {
    return isGirl() && isBeautiful();
}

当你被自己的代码逼迫,以致要写注释之前,你应该问自己:是不是这段代码写得太糟了?要么再改改?

4. 千万不要写中文注释

虽然代码往往都是以英文为基础的,代码旁边配以大段的英文注释也确实令人抓狂。

但是比英文更令人抓狂的是乱码

更令人抓狂的是,怎么转换都是乱码乱码

/**
 * ��Ҳ��֪�����Ǹ�ʲô��
 */
public void doSomething() {
}

谁能把这个乱码转回去,看看我注释里写了什么?

另外,是不是有一种删掉的冲动?

好的代码本身就是注释

Person person = I.meet();
if (person instanceof Girl) {
    Girl she = (Girl) person;
    if (she.isBeautiful()) {
        if (she.isKind()) {
            I.marry(she);
        } else if (she.isBitch()) {
            I.fuck(she);
        } else {
            I.play(she);
        }
    } else {
        I.doNothing();
    }
} else {
    I.stayLonely();
}

以上代码,虽然if深了一点,但是不需要注释也完全可读。哪怕从自然语言的语法角度看也问题多多,不过,代码的逻辑就在那里,比任何自然语言更准确地描述了程序的实际运行状况。

There are a thousand Hamlets in a thousand people's eyes.

一千个读者就有一千个哈姆雷特。

——莎士比亚(Shakespeare)

如果你强行要把编程语言编译成自然语言,你能确定你表达了你想表达的,你确定你想表达的就是程序实际运行的?

你确定没有犯前面的四类问题?
注释,需要是表达了和代码相同涵义(第1类问题)、而又不能是相同语意(第2类问题)、在代码比较复杂或难读(第3类问题)、并且不能用ASCII以外的字符的情况下,写在代码旁边解释代码的东西。

(其实一句话就能打败大多数中国程序员:你英文写得比代码好?)

所以,还是让一切尽在代码中吧!

Code is poetry.

log即注释

在实际的工作中,你可以不写注释,但不得不写log。

注释是写给代码阅读者看的,并不参与编译。仅存在与代码中,编译后的软件里并不存在。

而log是为了调试、后续debug的方便而添加的。良好的log,可以让我们在log文件中,看清软件的实际运行状态。

在阅读代码时,

一些例外

注释,这种语法的存在还是有必要的,只是大部分程序员其实根本用不到、或用了以后应该马上删除。

API

例如,最应该写注释的,是提供给别人——通常是另一个team、甚至公司——用的public接口,也就是所谓API。
Java的API文档,往往是通过javadoc生成的。这样的好处是,开发代码的同时开发文档,保持一致性。

不过通常不需要太多维护,因为公开的API是不能随意修改的,最大的改动往往是加一个@deprecated
所以,其实API文档分开单独写也不是不可以。

内部用的public,代码实现都能被看见,文档也就可以免了。
实在是没有文档看不懂代码,不会问吗?

干“脏活儿”

有时候,需要表达的逻辑本身就很复杂。典型而又常见的就是多线程,往往难以理解和跟踪。

很多时候,某些语言,尤其是C语言,干的都是些“脏活儿”。为了保证性能,往往必须怎么高效怎么来。一些递归函数里,多定义一个变量,都能影响到空间复杂度。

干脏活儿,想不脏,不容易。

不过,如果真的比较复杂,还是单独的文档,或者UML图比较有效。

汇编就更不用提了。这个时代,你能写,你不能指望别人能看。

TODO和FIXME

这俩,说是注释,其实应该算是标记。

不过,程序员的一大恨事就是:在别人release过来的代码里,发现这哥俩!

临时去掉一些代码

调试时常用注释来disable一些代码,以免删除了还得重写或粘贴。

但是,调试完成后,不要的代码一定要删掉!

结论

上一篇 下一篇

猜你喜欢

热点阅读