目錄**內文件在軟體設計中起著至關重要的作用。注釋對於幫助開發人員理解系統和有效地工作是必不可少的,但是注釋的作用遠遠不止於此。文件在抽象中也扮演著重要的角色;沒有注釋,就無法隱藏複雜性。最後,編寫注釋的過程如果處理正確,實際上將改進系統的設計。相反,如果沒有良好的文件記錄,好的軟體設計就會失去很多價值。
不幸的是,這一觀點並沒有得到普遍認同。相當一部分產品**基本上不包含注釋。許多開發人員認為注釋是浪費時間;另一些人看到了注釋的價值,但不知何故卻從來沒有寫過。幸運的是,許多開發團隊認識到了文件的價值,並且感覺這些團隊的流行程度正在逐漸增加。然而,即使是在鼓勵文件化的團隊中,注釋也常常被看作是苦工的工作,許多開發人員不知道如何編寫注釋,因此生成的文件通常是平庸的。不充分的文件會對軟體開發造成巨大且不必要的拖累。
在本章中,我將討論開發人員用來避免編寫注釋的藉口,以及注釋真正重要的原因。第13章將描述如何寫出好的注釋,接下來的幾章將討論相關的問題,比如選擇變數名以及如何使用文件來改進系統的設計。我希望這些章節能讓你相信三件事:好的注釋可以使軟體的整體質量有很大的不同;寫出好的注釋並不難;而且(這可能很難相信)寫注釋其實很有趣。
在下面的章節中,我將依次解釋這些藉口。
有些人認為,如果**寫得好,那麼顯然不需要注釋。這是乙個美味的神話,就像冰淇淋有益健康的謠言:我們真的願意相信它。不幸的是,事實並非如此。當然,在編寫**時可以做一些事情來減少注釋的需要,比如選擇合適的變數名(參見第14章)。儘管如此,仍然有大量的設計資訊不能用**表示。例如,只能在**中正式指定類介面的一小部分,如其方法的簽名。介面的非正式方面,例如每個方法的高階描述或其結果的含義,只能在注釋中進行描述。還有許多其他的例子無法在**中描述,比如特定設計決策的基本原理,或者呼叫特定方法的條件。
一些開發人員認為,如果其他人想知道乙個方法做什麼,他們應該只閱讀方法的**:這將比任何注釋更準確。讀者可以通過閱讀**來推斷方法的抽象介面,但這將是耗時且痛苦的。此外,如果您編寫**時期望使用者能夠讀取方法實現,那麼您將嘗試使每個方法盡可能短,以便於讀取。如果該方法做了任何重要的事情,您將把它分解成幾個更小的方法。這將導致大量的淺方法。而且,它並沒有真正使**更容易閱讀:為了理解頂級方法的行為,讀者可能需要理解巢狀方法的行為。對於大型系統,使用者通過閱讀**來學習行為是不現實的。
此外,注釋是抽象的基礎。回顧第4章,抽象的目標是隱藏複雜性:抽象是實體的簡化檢視,它保留了基本資訊,但忽略了可以安全忽略的細節。如果使用者必須閱讀方法的**才能使用它,那麼就沒有抽象:方法的所有複雜性都暴露出來了。如果沒有注釋,方法的惟一抽象就是它的宣告,它指定了方法的名稱、引數和結果的名稱和型別。宣告缺少太多的基本資訊,無法提供乙個有用的抽象。例如,提取子字串的方法可能有兩個引數,start和end,表示要提取的字元的範圍。僅從宣告中無法判斷提取的子字串是否包含end所指示的字元,或者如果開始》結束會發生什麼。注釋允許我們捕獲呼叫者需要的附加資訊,從而在隱藏實現細節的同時完成簡化的檢視。同樣重要的是,注釋是用英語等人類語言寫的;這使得它們不如**精確,但它提供了更強的表達能力,因此我們可以建立簡單、直觀的描述。如果您想使用抽象來隱藏複雜性,注釋是必不可少的。
人們傾向於優先考慮比其他開發任務更低的注釋。如果要在新增新特性和記錄現有特性之間進行選擇,那麼選擇新特性似乎是合乎邏輯的。然而,軟體專案幾乎總是處於時間壓力之下,而且總是有一些事情看起來比寫注釋更重要。因此,如果您允許取消文件的優先順序,那麼最終將沒有文件。
這個藉口的反面論據是第15頁所討論的投資心態。如果您想要乙個乾淨的軟體結構,它將允許您在長期內高效地工作,那麼您必須預先花一些額外的時間來建立這個結構。好的注釋會對軟體的可維護性產生巨大的影響,因此花在注釋上的精力很快就會得到回報。此外,寫注釋不需要花很多時間。問問你自己你花了多少開發時間來打字(相對於設計、編譯、測試等等),假設你沒有任何注釋;我懷疑答案是否超過10%。現在假設您輸入注釋的時間與輸入**的時間一樣多;這應該是乙個安全的上限。根據這些假設,寫出好的注釋不會增加超過10%的開發時間。擁有良好文件的好處將很快抵消這一成本。
此外,許多最重要的注釋都與抽象相關,比如類和方法的頂級文件。第15章將討論這些注釋應該作為設計過程的一部分來編寫,而編寫文件的行為可以作為改進整體設計的重要設計工具。這些注釋立竿見影。
注釋有時確實會過時,但這在實踐中不一定是主要問題。保持文件更新不需要付出巨大的努力。只有在對**進行了較大更改的情況下,才需要對文件進行較大的更改,並且**更改將比文件更改花費更多的時間。第16章討論了如何組織文件,以便在**修改後盡可能輕鬆地更新文件(關鍵思想是避免重複的文件,並使文件與相應的**保持一致)。**審查為檢測和修復陳舊的注釋提供了一種很好的機制。
在這四個藉口中,這可能是最有價值的乙個。每個軟體開發人員都看到過沒有提供任何有用資訊的注釋,而且大多數現有文件充其量也就是一般。幸運的是,這個問題是可以解決的;編寫可靠的文件並不難,只要您知道如何做到這一點。下一章將為如何編寫良好的文件並隨時間進行維護提供乙個框架。
既然我已經討論了(希望已經揭穿了)反對寫注釋的爭論,讓我們考慮一下從好的注釋中可以得到的好處。注釋背後的總體思想是捕獲設計者頭腦中但是不能在**中表示的資訊。這些資訊的範圍很廣,從底層的細節(比如驅動一段特別複雜的**的硬體怪癖),到高層的概念(比如類的基本原理)。當其他開發人員稍後進行修改時,注釋將允許他們更快更準確地工作。沒有文件,未來的開發人員將不得不重新推導或猜測開發人員的原始知識;這將花費額外的時間,並且如果新開發人員誤解了原始設計人員的意圖,就會有出現bug的風險。即使是最初的設計人員做出了更改,注釋也是很有價值的:如果距離您最後一次使用**已經超過幾個星期了,那麼您就會忘記最初設計的許多細節。
第二章描述了複雜性在軟體系統中表現出來的三種方式:
好的文件有助於解決最後兩個問題。通過向開發人員提供他們需要更改的資訊,並使開發人員很容易忽略不相關的資訊,文件可以減少認知負荷。如果沒有足夠的文件,開發人員可能不得不閱讀大量的**來重構設計者的想法。文件還可以通過澄清系統的結構來減少未知的未知,這樣就可以清楚哪些資訊和**與任何給定的更改相關。
第二章指出了複雜性的主要原因是依賴性和模糊性。好的文件可以澄清依賴關係,並填補空白以消除模糊性。
接下來的幾章將向您展示如何編寫好的文件。他們還將討論如何將文件編寫整合到設計過程中,從而改進軟體的設計。
軟體設計的哲學 第二十一章 結論
目錄這本書講的是一件事 複雜性。處理複雜性是軟體設計中最重要的挑戰。它使系統難於構建和維護,並且常常使它們變慢。在這本書中,我試圖描述導致複雜性的根本原因,比如依賴性和模糊性。我已經討論了可以幫助您識別不必要複雜性 如資訊洩漏 不必要的錯誤條件或過於通用的名稱 的危險訊號。我已經介紹了一些您可以用來...
羊皮卷的實踐 第二十章
第二十章 你可以在任何乙個星期一開始填寫你的成功記錄表。一旦開始,就不能中斷,除非嚴重的疾病。還有乙個例外。如果在你執行這項計畫的過程中,碰巧有一次休假,那麼儘管讓自己去享受假日的輕鬆。然後,一旦假期結束,就立刻繼續執行計畫。現在你要開始閱讀第一張羊皮卷。這一捲會告訴你閱讀其它幾卷的方法以及時間的安...
軟體設計的哲學 翻譯 目錄
2020年必讀書籍推薦 軟體設計的哲學 a philosophy of software design 本書190多頁,豆瓣的點評分在9分以上,目前只有英文版本,中文版還未上市,英文好的同學建議去直接閱讀原版。john ousterhout是史丹福大學電腦科學教授。他目前的研究重點是新的軟體堆疊層,...