1. 程式人生 > >程式碼潔癖系列(四):可忽略的注

程式碼潔癖系列(四):可忽略的注

剛開始學程式設計的時候,老師就告訴我們,註釋很重要,但是一直到現在,也沒有人真正告訴過我要怎麼寫註釋。還有很多人甚至乾脆不寫註釋。所以今天想聊一下到底如何寫註釋。

提到註釋就讓我想起一個段子:兩個程式設計師去飯店吃飯,點菜的時候程式設計師甲說:我要吃宮保雞丁,程式設計師乙就幫他記。

宮保雞丁

然後程式設計師甲又說:我不想吃宮保雞丁了,換成地三鮮吧。程式設計師乙就說好的,然後又幫他記上了。

//宮保雞丁
地三鮮

這個段子也從側面反映了程式設計師們習慣性忽略註釋的事實。段子講完了,下面插播一些正文。

註釋不能拯救糟糕的程式碼

首先,我想說的可能和大多數人的觀點相左:儘量少用註釋!沒錯,儘量少用。因為註釋是會騙人的,而且時間越長的註釋越容易騙人,因為大部分人在修改程式碼的時候都不會去修改註釋。少寫註釋,儘量用程式碼去描述你要做什麼。當你要寫註釋的時候,就要思考一下,別人為什麼不能通過程式碼理解你想表達什麼。這時你需要嘗試修改程式碼,來達到上述目的。

// Check to see if the employee is eligible for full benefits
if (employee.flags & HOURLY_FLAG) &&
    (employee.age > 65)

看一下這段程式碼,如果只看程式碼,可以理解它要表達什麼嗎?

if (employee.isEligibleForFUllBenefits())

花上點時間,把程式碼改成這樣,是不是不用註釋也可以讀懂了?

我們這裡說盡量少使用註釋,並不是完全不用註釋,在某些情況下,我們需要註釋。那麼什麼樣的註釋才算是好的註釋呢?

法律資訊

有時,公司程式碼規範會要求註明版權和著作權。那麼我們就應該將這些資訊放到原始檔的開頭位置。

提供資訊的註釋

// Returns an instance of the Responder being tested.
protected abstract Responder responderInstance()

這樣的註釋就是不錯的註釋,給讀者提供了返回值的資訊,不過,如果我們把函式命名為responderBeingTested,那麼這個註釋也就顯得多餘了。

闡釋

可以用註釋把某些難以理解的引數或返回值翻譯成可以理解的形式。當前,前提是如果這些程式碼你無法修改,比如引數或返回值是標準庫的一部分。這時闡釋就顯得很有用。舉過來一個栗子。

assertTrue(a.compareTo(a) == 0);  // a == a
assertTrue(a.compareTo(b) != 0);  // a != b
assertTrue(a.compareTo(b) == -1); // a < b

不過這樣的闡釋也有缺點,那就是它有可能是不正確的,我們需要小心確認其正確性。如果缺失正確性,那麼這樣的闡釋只會起到負面作用。

TODO註釋

TODO註釋是比較常用的註釋,可以在程式碼裡新增工作列表,例如,對一個空實現函式新增TODO註釋,就可以解釋這裡為什麼是空實現,以及以後要實現什麼。

公共API的Javadoc

這個也許最令人欣賞的註釋習慣了。不過目前我們通常用swagger來代替註釋。對swagger感興趣的童鞋可以戳這裡

所謂見賢思齊焉,見不賢而內自省也。看完了好的註釋,就要想想怎麼才能寫出好的註釋;接下來再來看看壞的註釋,看的同時需要多反省自己,儘量避免寫出壞的註釋。

自說自話

寫的東西只有自己能看懂,別人都不明白要表達什麼。如果讀程式碼時連註釋都看不明白,還有人想看下去嗎。

日誌式註釋

幾乎把程式碼的每次修改記錄都寫到註釋裡,也許在那個沒有程式碼版本控制工具的遠古時代,這麼做還有一定的意義。但是現在我們擁有很多健壯的程式碼版本控制工具,這樣的註釋也就變得毫無意義。

在程式碼里加上自己的簽名也是一樣的道理,我們都可以通過程式碼版本控制工具檢視具體的建立者和修改者,而不是隻記住建立者。

註釋掉程式碼也是一樣,我們用版本控制工具可以輕鬆找回以前的程式碼,不需要的程式碼可以直接刪掉,而不是留一個註釋掉的程式碼放在那裡。

廢話註釋

/** The day of the month. */
private int dayOfMonth;

我不想多廢話了……

結語

也許文中的觀點和大多數人的思維相左,可能我的有些觀點是錯的,歡迎大家關注我的微信公眾號,和我討論註釋究竟是否必要。

這裡寫圖片描述