8個最沒有意義的程式碼註釋

John Vester發表於2016-02-17

多年來,我非常榮幸能和一些謙遜的公司和客戶合作。我也因此有機會接觸到各種不同的程式設計師—— 每個程式設計師都有自己獨特的風格。事實上,每個專案本身都有一些獨特的元素。

這些特質的交叉讓我去思考我曾經審查、更新或提高過的程式程式碼。與其說是程式碼的實際邏輯,還不如說是開發人員自己新增到程式碼中的註釋,對程式碼產生了頗為深遠的影響。這篇文章的主題就是羅列一些我印象深刻的一些程式碼註釋。

因為Carol讓我這麼做

我記得審查程式程式碼時,有一條註釋是這樣寫的:

// Because Carol Told Me to Do This

在閱讀這行程式碼時,我一下子就懵了,“誰是Carol?”以及“Carol讓這個開發人員做什麼了?”雖然寫程式碼的程式設計師知道這兩個答案,但換做是一個局外人或者是一個後面加進來的人,那麼這條註釋就毫無價值。當我和我的經理說起這條註釋的時候,他哈哈大笑,只是說了句Carol明顯是一個人名字之後,就無下文了。好吧,直到現在,我依然不知道這句註釋究竟是什麼意思。

大段被註釋的程式碼

在另一種情況下,我相信我將問題範圍縮小到了一個特定的類。但是開啟這個類,我看到大量的程式碼被塊註釋掉了。讓人瘋狂的是,註釋的程式碼是在方法的中間。所以,我只能在閱讀完頂部的程式碼之後,滾動幾個螢幕,才能繼續閱讀剩下的程式碼。你得牢記在心裡,幸好中間間隔的時間不是太久,有到應用程式的原始碼庫的連結。

在我心中,我對此非常嗤之以鼻,“提前閱讀沒有註釋的大塊程式碼,卻只是看到了程式是用來做什麼的”。當我問另一名開發人員為什麼程式碼要像這樣被註釋和檢查的時候,他給我的回答是“萬一我們下次還要用到它呢”。我真心無語。

只是為了苦中作樂

在工作於一個基於web的應用程式時,我發現了以下的JavaScript註釋:

// make sure it's correctly formatted, because in javascript things
// like '7' or '4.3' or 'derpdy do 77' are valid dates
// seriously, try it out for yourself: Date.parse('derpdy do 77')

這裡的開發人員意識到Date.parse()方法存在著問題。為了警示他人,開發人員決定新增註釋作為警告,同時又苦中作樂了一番。我只能想象當這個開發人員意識到此路不通時心中該是有多麼的沮喪。

道歉

有些時候,程式設計師意識到他們的做法並不好。很多時候,這是基於開發小組之外所能做的唯一選擇。於是,出現了這樣的註釋:

// Sorry for what you are about to see

閱讀程式碼和理解實施方法背後的情況有助於完整地理解簡單的道歉式註釋。這有點像驚悚片裡的英雄在採取有計劃的行動之前,先道歉的那一幕。

只圍繞它編碼

一開始作為一個白板宣告,最終被轉移到以下注釋:

// Doing this to "not do anything to effect Eric and Steve's code"

基本上,這是一個程式的入口點,程式碼圍繞明顯由Eric和Steve引入的問題。但是我沒有任何相關的背景,也不認識Eric和Steve,我只知道任何影響了他們的程式碼都得禁止。

為了註釋而註釋

我們都聽過這樣一句話:“好的程式碼是自文件化的”。我完全同意這種說法,當然有些註釋還是有必要的。但是,下面這種註釋,明顯不能劃到“必要”的範疇中:

return true; // returns true

這種註釋確明顯是沒有必要的,因為我們很容易理解返回什麼。我能想出的關於為什麼要這麼註釋的唯一原因就是,開發人員在新增到實際程式碼前,使用註釋先制定出了方法,後來卻忘記刪掉這些註釋了。但是如果有程式碼審查過程的話,就不會出現這樣的註釋。

註釋不正確

還記得前面提過的“好的程式碼是自文件化的”這句話嗎?那麼,也許在所有註釋中,最糟糕的就是提供了錯誤資訊的註釋。請看下面這個簡單的例子:

// Always returns false
public boolean isActive() {
    return true;
}

現實中我所看到的例子遠遠沒有這麼簡單。然而更糟糕的是,當你需要依賴註釋寫一個複雜的方法時,才意識到這樣的註釋是無效的。在這種情況下沒有註釋都比錯誤的註釋好。

小說般的註釋

最後一種我見過的註釋是,開發人員寫的類似於小說般的註釋:

/**
* This is the widget method which will process the list of
* widgets from the widget controller and service in order to
* handle pre-processing (where the widget information is
* compared against the average widget history), actual
* processing (where the quarterly, monthly and week attributes
* are updated) and all of the post-processing (which include the
* analytical metrics and audit table updates) aspects. It is
* important to remember the widget rules around leap year where
* the cost to transfer rate is 75% adjusted to the annual rate in
* order to account for the extra day. When this happens, the
* process will throw the LeapYearException which will need to be
* validated by the application support staff. Failure to do so will
* end up causing issues with the ME-4110 report.
*/

我的經驗法則是,任何需要那麼多資訊的程式碼或許應該分解成更小的方法。而且註釋中這樣的資訊應該挪到實際的程式碼之外。而在上面的例子中,像流水賬一樣記錄的業務規則和業務流程——卻有可能隨著時間而改變。

結論

關於如何正確地寫好程式碼註釋,簡單地搜一下的話,網上有很多很多。有些甚至可能會告訴你如何儘可能地不在程式碼中提供註釋。

相反,我想分享一些我有幸作為一個應用程式開發人員所讀過的一些滑稽的註釋。請記住,我在應用程式開發上有著20年以上的編譯經驗——反映了例外,而不是規則。

編碼快樂!

相關文章