為什么要寫注釋


代碼內文檔在軟件設計中起着至關重要的作用。 注釋對於幫助開發人員理解系統和有效地工作是必不可少的,但是注釋的作用遠遠不止於此。文檔在抽象中也扮演着重要的角色;沒有注釋,就無法隱藏復雜性。最后,編寫注釋的過程如果處理正確,實際上將改進系統的設計。相反,如果沒有良好的文檔記錄,好的軟件設計就會失去很多價值。

不幸的是,這一觀點並沒有得到普遍認同。相當一部分產品代碼基本上不包含注釋。許多開發人員認為注釋是浪費時間;另一些人看到了注釋的價值,但不知何故卻從來沒有寫過。幸運的是,許多開發團隊認識到了文檔的價值,並且感覺這些團隊的流行程度正在逐漸增加。然而,即使是在鼓勵文檔化的團隊中,注釋也常常被看作是苦工的工作,許多開發人員不知道如何編寫注釋,因此生成的文檔通常是平庸的。不充分的文檔會對軟件開發造成巨大且不必要的拖累。

在本章中,我將討論開發人員用來避免編寫注釋的借口,以及注釋真正重要的原因。第13章將描述如何寫出好的注釋,接下來的幾章將討論相關的問題,比如選擇變量名以及如何使用文檔來改進系統的設計。我希望這些章節能讓你 相信三件事:好的注釋可以使軟件的整體質量有很大的不同;寫出好的注釋並不難;而且(這可能很難相信)寫注釋其實很有趣。

當開發人員不寫注釋時,他們通常會用以下一個或多個理由來解釋他們的行為:

  • 好的代碼是自我解釋的。
  • 我沒時間寫注釋。
  • 注釋過時了,會產生誤導。
  • 我所看到的注釋都是毫無價值的,何苦呢?

在下面的章節中,我將依次解釋這些借口。

12.1 好代碼是自我解釋的

有些人認為,如果代碼寫得好,那么顯然不需要注釋。這是一個美味的神話,就像冰淇淋有益健康的謠言:我們真的願意相信它。不幸的是,事實並非如此。當然,在編寫代碼時可以做一些事情來減少注釋的需要,比如選擇合適的變量名(參見第14章)。盡管如此,仍然有大量的設計信息不能用代碼表示。例如,只能在代碼中正式指定類接口的一小部分,如其方法的簽名。接口的非正式方面,例如每個方法的高級描述或其結果的含義,只能在注釋中進行描述。還有許多其他的例子無法在代碼中描述,比如特定設計決策的基本原理,或者調用特定方法的條件。

一些開發人員認為,如果其他人想知道一個方法做什么,他們應該只閱讀方法的代碼:這將比任何注釋更准確。讀者可以通過閱讀代碼來推斷方法的抽象接口,但這將是耗時且痛苦的。此外,如果您編寫代碼時期望用戶能夠讀取方法實現,那么您將嘗試使每個方法盡可能短,以便於讀取。如果該方法做了任何重要的事情,您將把它分解成幾個更小的方法。這將導致大量的淺方法。而且,它並沒有真正使代碼更容易閱讀:為了理解頂級方法的行為,讀者可能需要理解嵌套方法的行為。對於大型系統,用戶通過閱讀代碼來學習行為是不現實的。

此外,注釋是抽象的基礎。回顧第4章,抽象的目標是隱藏復雜性:抽象是實體的簡化視圖,它保留了基本信息,但忽略了可以安全忽略的細節。如果用戶必須閱讀方法的代碼才能使用它,那么就沒有抽象:方法的所有復雜性都暴露出來了。如果沒有注釋,方法的惟一抽象就是它的聲明,它指定了方法的名稱、參數和結果的名稱和類型。聲明缺少太多的基本信息,無法提供一個有用的抽象。例如,提取子字符串的方法可能有兩個參數,start和end,表示要提取的字符的范圍。僅從聲明中無法判斷提取的子字符串是否包含end所指示的字符,或者如果開始>結束會發生什么。注釋允許我們捕獲調用者需要的附加信息,從而在隱藏實現細節的同時完成簡化的視圖。同樣重要的是,注釋是用英語等人類語言寫的;這使得它們不如代碼精確,但它提供了更強的表達能力,因此我們可以創建簡單、直觀的描述。如果您想使用抽象來隱藏復雜性,注釋是必不可少的。

12.2 我沒有時間寫注釋

人們傾向於優先考慮比其他開發任務更低的注釋。如果要在添加新特性和記錄現有特性之間進行選擇,那么選擇新特性似乎是合乎邏輯的。然而,軟件項目幾乎總是處於時間壓力之下,而且總是有一些事情看起來比寫注釋更重要。因此,如果您允許取消文檔的優先級,那么最終將沒有文檔。

這個借口的反面論據是第15頁所討論的投資心態。如果您想要一個干凈的軟件結構,它將允許您在長期內高效地工作,那么您必須預先花一些額外的時間來創建這個結構。好的注釋會對軟件的可維護性產生巨大的影響,因此花在注釋上的精力很快就會得到回報。此外,寫注釋不需要花很多時間。問問你自己你花了多少開發時間來打字(相對於設計、編譯、測試等等),假設你沒有任何注釋;我懷疑答案是否超過10%。現在假設您輸入注釋的時間與輸入代碼的時間一樣多;這應該是一個安全的上限。根據這些假設,寫出好的注釋不會增加超過10%的開發時間。擁有良好文檔的好處將很快抵消這一成本。

此外,許多最重要的注釋都與抽象相關,比如類和方法的頂級文檔。第15章將討論這些注釋應該作為設計過程的一部分來編寫,而編寫文檔的行為可以作為改進整體設計的重要設計工具。這些注釋立竿見影。

12.3 注釋會過時並產生誤導

注釋有時確實會過時,但這在實踐中不一定是主要問題。保持文檔更新不需要付出巨大的努力。只有在對代碼進行了較大更改的情況下,才需要對文檔進行較大的更改,並且代碼更改將比文檔更改花費更多的時間。第16章討論了如何組織文檔,以便在代碼修改后盡可能輕松地更新文檔(關鍵思想是避免重復的文檔,並使文檔與相應的代碼保持一致)。代碼審查為檢測和修復陳舊的注釋提供了一種很好的機制。

12.4 我所看到的一切注釋都是毫無價值的

在這四個借口中,這可能是最有價值的一個。每個軟件開發人員都看到過沒有提供任何有用信息的注釋,而且大多數現有文檔充其量也就是一般。幸運的是,這個問題是可以解決的;編寫可靠的文檔並不難,只要您知道如何做到這一點。下一章將為如何編寫良好的文檔並隨時間進行維護提供一個框架。

12.5 良好的注釋的好處

既然我已經討論了(希望已經揭穿了)反對寫注釋的爭論,讓我們考慮一下從好的注釋中可以得到的好處。注釋背后的總體思想是捕獲設計者頭腦中但是不能在代碼中表示的信息。這些信息的范圍很廣,從底層的細節(比如驅動一段特別復雜的代碼的硬件怪癖),到高層的概念(比如類的基本原理)。當其他開發人員稍后進行修改時,注釋將允許他們更快更准確地工作。沒有文檔,未來的開發人員將不得不重新推導或猜測開發人員的原始知識;這將花費額外的時間,並且如果新開發人員誤解了原始設計人員的意圖,就會有出現bug的風險。即使是最初的設計人員做出了更改,注釋也是很有價值的:如果距離您最后一次使用代碼已經超過幾個星期了,那么您就會忘記最初設計的許多細節。

第二章描述了復雜性在軟件系統中表現出來的三種方式:

  • 變更放大:一個看似簡單的變更需要在很多地方修改代碼。
  • 認知負荷:為了做出改變,開發人員必須積累大量的信息。
  • 未知的未知:不清楚需要修改哪些代碼,或者為了進行這些修改必須考慮哪些信息。

好的文檔有助於解決最后兩個問題。通過向開發人員提供他們需要更改的信息,並使開發人員很容易忽略不相關的信息,文檔可以減少認知負荷。如果沒有足夠的文檔,開發人員可能不得不閱讀大量的代碼來重構設計者的想法。文檔還可以通過澄清系統的結構來減少未知的未知,這樣就可以清楚哪些信息和代碼與任何給定的更改相關。

第二章指出了復雜性的主要原因是依賴性和模糊性。好的文檔可以澄清依賴關系,並填補空白以消除模糊性。

接下來的幾章將向您展示如何編寫好的文檔。他們還將討論如何將文檔編寫集成到設計過程中,從而改進軟件的設計。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM