coding時盡量不要寫注釋

coding時盡量不要寫注釋

在學(xué)校里學(xué)習(xí)時,老師對注釋的要求比較嚴(yán)苛。

你寫代碼的時候不寫注釋,過一段時間你自己都看不懂了,何況別人?

上一句還屬于常規(guī)觀點。某個老師甚至這么說:

C語言,注釋量應(yīng)該和代碼量相當(dāng)。

當(dāng)時,我是心中敬仰的。然而,工作后發(fā)現(xiàn),實際工程領(lǐng)域之中,并沒有那么多注釋。
而且,逐漸發(fā)現(xiàn),大部分情況下不需要、也不應(yīng)該注釋。

由于工作中以Java為主——這真是一個悲傷的故事——以下代碼以Java為例。

1. 錯誤的注釋不如沒有

注釋寫出來,就是給人看的。如果注釋是錯的,就會誤導(dǎo)代碼閱讀者。

/**
 * 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();
}

比如上面那段,代碼是個同性戀寫的,注釋的則是異性戀;或者,當(dāng)他寫注釋的時候以為自己性取向很正常,寫代碼的時候心中忽然涌上一陣明悟……

這類注釋在實際工作中碰到很多。在維護(hù)代碼、或者是在以前的基礎(chǔ)上開發(fā)代碼的過程中,往往是進(jìn)行增量修改。某些時候,Method內(nèi)的實現(xiàn)已經(jīng)改了,而代碼注釋未變,就容易出現(xiàn)二者不一致,甚至意義完全相反。

修改代碼時,一定要先修改相關(guān)注釋。這就帶來了維護(hù)成本的提高。

問題是:增加的維護(hù)成本以及誤導(dǎo)幾率,是否能被注釋帶來的收益所抵消?

2. 沒有額外語意的注釋不如不寫

注釋不僅要說明,還必須要有額外語意,或者更簡單地表達(dá)了與代碼實際效果相同的意思。

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

上面那段,這樣的注釋,有什么意義?

  • name不就是name嗎?難道還需要再說一遍,或者翻譯成中文?
  • phoneNumber不就是電話號碼嗎?難道要在注釋里拆開,代碼的閱讀者才能看懂?

這類為了注釋而注釋的注釋,除了礙眼,并無意義。而且,還容易出現(xiàn)第1類問題。

比如,以后人類都不用注冊、購買電話號碼了,直接用身份證號作為聯(lián)系方式。上面的代碼需要把phoneNumber改為id,修改者會不會記得改注釋?

他心中一定有一萬頭草泥馬在狂奔:還不如刪掉!

3. 必要的注釋是代碼的失敗

其實,看代碼的人都是碼農(nóng)……呃,我是指,看代碼的人都是能看代碼的人。一般不會存在沒有注釋就看不懂的代碼。

注釋只不過是加速理解代碼的過程。

而且,看了注釋,不代表就不需要看代碼。因為有可能存在第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的注釋已經(jīng)寫得很清楚了,isGood()是看這個人是不是個美女。
這段注釋的確加速了理解,因為isGood()并不是很直觀。什么樣的好才是好?

但是,為什么不把Method命名為isBeautifulGirl()?表達(dá)了同樣意義的同時,也不用閱讀者跳轉(zhuǎn)到定義位置來看。

其次,在實現(xiàn)中的這段注釋的確加速了理解,不然這個位操作要看很久(視腦年齡而定)。

但是,特么誰準(zhǔn)你在Java里用位操作?!

不管你這個int里存了多少位的信息,為什么不能拆分成多個值?
如果拆分成多個值,每個值都給予恰當(dāng)?shù)拿湟赃m當(dāng)?shù)腗ethod,為什么還需要注釋?

例如以下代碼,需要注釋嗎?

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

當(dāng)你被自己的代碼逼迫,以致要寫注釋之前,你應(yīng)該問自己:是不是這段代碼寫得太糟了?要么再改改?

4. 千萬不要寫中文注釋

雖然代碼往往都是以英文為基礎(chǔ)的,代碼旁邊配以大段的英文注釋也確實令人抓狂。

但是比英文更令人抓狂的是亂碼!

更令人抓狂的是,怎么轉(zhuǎn)換都是亂碼亂碼!

/**
 * ?????????????????
 */
public void doSomething() {
}

誰能把這個亂碼轉(zhuǎn)回去,看看我注釋里寫了什么?

另外,是不是有一種刪掉的沖動?

好的代碼本身就是注釋

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深了一點,但是不需要注釋也完全可讀。哪怕從自然語言的語法角度看也問題多多,不過,代碼的邏輯就在那里,比任何自然語言更準(zhǔn)確地描述了程序的實際運行狀況。

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

一千個讀者就有一千個哈姆雷特。

——莎士比亞(Shakespeare)

如果你強(qiáng)行要把編程語言編譯成自然語言,你能確定你表達(dá)了你想表達(dá)的,你確定你想表達(dá)的就是程序?qū)嶋H運行的?

你確定沒有犯前面的四類問題?
注釋,需要是表達(dá)了和代碼相同涵義(第1類問題)、而又不能是相同語意(第2類問題)、在代碼比較復(fù)雜或難讀(第3類問題)、并且不能用ASCII以外的字符的情況下,寫在代碼旁邊解釋代碼的東西。

(其實一句話就能打敗大多數(shù)中國程序員:你英文寫得比代碼好?)

所以,還是讓一切盡在代碼中吧!

Code is poetry.

log即注釋

在實際的工作中,你可以不寫注釋,但不得不寫log。

注釋是寫給代碼閱讀者看的,并不參與編譯。僅存在與代碼中,編譯后的軟件里并不存在。

而log是為了調(diào)試、后續(xù)debug的方便而添加的。良好的log,可以讓我們在log文件中,看清軟件的實際運行狀態(tài)。

在閱讀代碼時,

一些例外

注釋,這種語法的存在還是有必要的,只是大部分程序員其實根本用不到、或用了以后應(yīng)該馬上刪除。

API

例如,最應(yīng)該寫注釋的,是提供給別人——通常是另一個team、甚至公司——用的public接口,也就是所謂API。
Java的API文檔,往往是通過javadoc生成的。這樣的好處是,開發(fā)代碼的同時開發(fā)文檔,保持一致性。

不過通常不需要太多維護(hù),因為公開的API是不能隨意修改的,最大的改動往往是加一個@deprecated。
所以,其實API文檔分開單獨寫也不是不可以。

內(nèi)部用的public,代碼實現(xiàn)都能被看見,文檔也就可以免了。
實在是沒有文檔看不懂代碼,不會問嗎?

干“臟活兒”

有時候,需要表達(dá)的邏輯本身就很復(fù)雜。典型而又常見的就是多線程,往往難以理解和跟蹤。

很多時候,某些語言,尤其是C語言,干的都是些“臟活兒”。為了保證性能,往往必須怎么高效怎么來。一些遞歸函數(shù)里,多定義一個變量,都能影響到空間復(fù)雜度。

干臟活兒,想不臟,不容易。

不過,如果真的比較復(fù)雜,還是單獨的文檔,或者UML圖比較有效。

匯編就更不用提了。這個時代,你能寫,你不能指望別人能看。

TODO和FIXME

這倆,說是注釋,其實應(yīng)該算是標(biāo)記。

  • TODO: 表示還有未完成的工作,往往是開發(fā)過程中使用。

  • FIXME: 表示這里有bug,或者可能有bug,但暫時無法解決。這往往是發(fā)布時用。

不過,程序員的一大恨事就是:在別人release過來的代碼里,發(fā)現(xiàn)這哥倆!

臨時去掉一些代碼

調(diào)試時常用注釋來disable一些代碼,以免刪除了還得重寫或粘貼。

但是,調(diào)試完成后,不要的代碼一定要刪掉!

結(jié)論

  • 趕緊刪注釋去!
  • 不要主動寫API以外的注釋!
  • 代碼要寫得好看一點。
  • 以后的工作中,誰叫寫注釋就有理有據(jù)地噴回去!
  • 你因看了本文而產(chǎn)生的任何實際變化,如果在工作和學(xué)習(xí)中帶來了任何負(fù)面結(jié)果,請自行負(fù)責(zé)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,355評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,699評論 19 139
  • 我從初中起就是在寄宿學(xué)校讀書,每周回去一次,周五放假,周末回去。回了家,無非就是看看電視劇,打打電子游戲,吃一頓可...
    雁書聽夏閱讀 395評論 2 3
  • 9月4日下午,聯(lián)保社區(qū)書記帶領(lǐng)全體工作人員清理社區(qū)路面及樓道內(nèi)的亂堆亂放雜物,并將雨陽棚上的垃圾清掃干凈。全面迎檢...
    謝小琦閱讀 189評論 0 0
  • 早加餐:油桃午加餐:西梅,麥片晚水果:獼猴桃 參考目標(biāo): 1份肉: <50g熟的畜禽水2份豆制品: 一小杯熟的豆子...
    靜趣_兒童心理師閱讀 247評論 0 0

友情鏈接更多精彩內(nèi)容