在大多數軟件工程師對編寫、使用和維護代碼的抱怨中,一個常見的問題是缺乏高質量的文檔。缺乏文檔有什么副作用呢?當遇到一個bug時,這個縮寫是什么意思?這份文件是最新的嗎?在整個職業生涯中,每個軟件工程師都抱怨過文檔的質量、數量或者完全缺乏文檔。
01
為什么需要寫文檔?
高質量文檔對工程組織有巨大的好處。代碼和api變得更容易理解。當他們的設計目標和團隊目標被清楚地陳述時,項目團隊會更加專注。當步驟被清晰地列出時,手動流程更容易遵循。如果過程被清楚地記錄下來,那么讓新成員進入團隊或代碼庫所花費的精力就會少得多。但是,由于文檔的好處有一定的滯后性,通常不會給作者帶來直接的好處。不像測試,編寫完測試用例,跑一遍就有結果。畢竟,你可能只編寫了一個文檔,但之后它將被閱讀數百次,甚至數千次;它的初始成本將攤銷給所有未來的讀者。文檔不僅可以隨著時間的推移而擴展,而且它對組織的其他部分的擴展也很關鍵。它有助于回答以下的問題:
為什么會做出這些設計決策?
為什么要以這種方式實現這段代碼?
為什么大多數工程師不喜歡寫文檔?
雖然文檔可以帶來不少好處,為什么工程師通常認為它是糟糕的?其中一個原因,正如我們提到的,是好處不是立竿見影的,特別是對作者來說。另外還有以下幾點:
很多工程師習慣將寫代碼和寫作割裂開,不僅僅是在工作上,而且在思想上就認為它們是完全不相關的兩項工作,這就導致好多人重代碼不重文檔。
也有很多工程師認為自己不善寫作,索性就不寫了。這實際是個偷懶的借口,寫文檔不需要華麗的辭藻、生動的語言,你只需要將問題講清楚即可。
有時候工具不好用也會影響的文檔寫作。如果沒有一個很好的寫作工具將寫文檔嵌入到開發工作流程中的話,寫作確實會增加工作的負擔。
大多數人將寫文檔看做是工作的額外負擔。我代碼都沒時間寫,哪有時間寫文檔!,這其實是錯誤的觀念,文檔雖然前期有投入,但能讓你代碼的后期維護成本大幅降低,磨刀不誤砍柴工這個道理相信大家都還是能理解的。
02
寫文檔的重要性
另外一個原因是文檔被視為需要維護的額外負擔,而不是使現有代碼的維護更容易的東西。寫文檔同樣對作者也有非常大的好處:
它有助于審視API。編寫文檔是確定API是否有意義的最可靠的方法之一。通常,編寫文檔本身會使工程師重新評估設計決策。如果你不能解釋它,不能定義它,那你可能還沒有設計好它。
它提供了維護的歷史記錄。在任何情況下,代碼中的技巧都應該避免,但是當你盯著兩年前編寫的代碼,試圖找出錯誤所在時,好的注釋將提供很大的幫助。
它使你的代碼看起來更專業。開發人員自然會認為文檔完備的API就是設計得更好的API。雖然情況并非總是如此,但它們通常是高度相關的。雖然這個好處聽起來像是表面文章,但事實并非如此:一個產品是否有良好的文檔通常是一個很好的指標。
這將減少其他用戶提出的問題。對于編寫文檔的人來說,隨著時間的推移這可能是最大的好處。如果你必須向某人解釋某件事不止一次,那么記錄該過程通常是有意義的。
03
像管理代碼一樣管理文檔
軟件工程師使用單一的、主要的編程語言來編寫程序,他們仍然經常使用不同的語言來解決特定的問題。工程師可能會編寫shell腳本或Python來運行命令行任務,或者他們可能會用c++編寫大部分后端代碼,但用Java編寫一些中間件代碼,等等。每種語言都是工具箱中的一種工具。文檔也應該如此:它是一種工具,用不同的語言編寫,以完成特定的任務。編寫文檔與編寫代碼沒有多大區別。與編程語言一樣,它有規則、特定的語法和樣式決定,通常是為了實現與代碼中類似的目的:加強一致性、提高清晰度和避免理解錯誤。文檔通常與代碼緊密耦合,因此應該盡可能地將其視為代碼。也就是說,文檔也應具有如下的屬性:
有明確的責任人維護;
有統一的內部規范;
定期更新;
有變更和評審機制;
有問題反饋和更新機制;
明確文檔的讀者是誰
工程師在編寫文檔時犯的一個最重要的錯誤是只為自己編寫文檔。這樣做是很自然的,并且為自己編寫代碼并非沒有價值:畢竟,你可能需要在幾年后查看這些代碼,并試圖弄清楚你曾經的想法。或者說在團隊較小的時候,大家的工作交集很大,因此也能看懂你的文檔,但是隨著組織的發展,問題就逐漸凸顯,新人會有這不同背景,團隊大了以后,工作內容開始細化,交集減少,這時候之前寫的文檔對他們來說可能就很難理解了。
因此在開始寫作之前,應該(正式或非正式地)確定文檔需要滿足的受眾。設計文件可能需要說服決策者。教程可能需要為完全不熟悉代碼庫的人提供非常明確的說明。API可能需要為該API的任何用戶(無論是專家還是新手)提供完整和準確的參考信息。好的文檔不需要修飾或完善。工程師在編寫文檔時所犯的一個錯誤是認為他們需要成為更好的作者。按照這個標準,很少有軟件工程師會寫。記住,我們的觀眾站在你曾經站過的地方,但沒有你新的領域知識。所以你不需要成為一個偉大的作家;你只需要找一個像你一樣熟悉這個領域的人。
04
文檔類型
作為工作的一部分,工程師會編寫各種不同類型的文檔:設計文檔、代碼注釋、操作文檔、項目頁面等等。這些都可以算作文檔。但重要的是要知道不同的類型,不要混合類型。一般來說,文檔應該有一個單一的目的。正如API應該做一件事并且做好一樣,避免在一個文檔中做幾件事。軟件工程師經常需要編寫幾種主要類型的文檔:
參考文檔,包括注釋
設計文檔;
教程;
概念性文檔;
1.參考文檔參考文檔是工程師最常編寫的文檔類型;事實上,他們經常需要每天寫一些參考文檔。代碼注釋是工程師必須維護的最常見的參考文檔形式。這些注釋可以分為兩個基本陣營:API注釋和實現注釋。這兩種用戶之間的區別:API注釋不需要討論實現細節或設計決策,也不要假設用戶和作者一樣精通API。但是實現注釋可以假定讀者有更多的領域知識,但是要注意不要假設得太多。
2.設計文檔
大多數公司在項目開始之前都需要有設計文檔。軟件工程師通常使用團隊批準的特定設計文檔模板來編寫建議的設計文檔。然后還需要在特定的團隊會議上討論或評論設計的細節。一個好的設計文檔應該涵蓋:
設計目標
實現策略
利弊權衡和具體決策
替代方案
各方案的優缺點
一份優秀的設計文件,一旦獲得批準,不僅可以作為歷史記錄,還可以作為項目是否成功實現其目標的衡量標準。大多數團隊會將他們的設計文檔進行歸檔,以便在后續的時間查看。在產品發布前檢查設計文檔通常是很有用的,以確保編寫設計文檔時所陳述的目標在發布時仍然是所陳述的目標(如果不是,那么文件或產品都可以進行相應的調整)。
3.教程每個軟件工程師,當他們加入一個新的團隊時,都會想要盡可能快地跟上進度。擁有一個引導人們完成新項目設置的教程是非常有價值的。通常情況下,編寫教程的最佳時機是你第一次加入一個團隊的時候。拿個記事本或其他方法做筆記,寫下一路上你需要做的所有事情,假設沒有領域知識或特殊的設置限制;完成之后,可能會知道在這個過程中所犯的錯誤和原因,然后可以編輯你的步驟,以獲得更精簡的教程。重要的是,寫下一路上你需要做的一切;盡量不要假定任何特定的設置、權限或領域知識。這類型的文檔寫作中,要求寫作者盡可能站在用戶的視角上思考,極力避免出現和用戶的認知偏差,力爭每個步驟做到明確無歧義,每兩個步驟之間做到緊密銜接。
4.概念性文檔有些代碼需要更深入的解釋或見解,而不是僅僅通過閱讀參考文檔就能得到的。在這些情況下,我們需要概念性文檔來提供api或系統的概述。
概念性文檔處理可能是API的庫概述、描述服務器中數據生命周期的文檔等。概念性文檔是用來擴充而不是替換參考文檔集的。有時候這和參考文檔會有些內容重復,,但主要還是為了更深層次的說明某些問題、解釋清楚某個概念。概念性文檔沒有必要涵蓋所有邊緣情況。在這種情況下,為了清晰度而犧牲一些準確性是可以接受的。概念性文件的要點在于傳達理解。概念文檔是最難編寫的文檔形式。因此,它們通常是軟件工程師工具箱中最容易被忽視的文檔類型。而且還有另外一個問題,沒合適的地方放,參考文檔可以寫代碼里,落地頁可以寫項目主頁里,概念性文檔似乎也只能在項目文檔里找個不起眼的角落存放了。概念文檔需要對廣泛的受眾有用:無論是專家還是新手。此外,它需要強調清晰性,所以它通常需要犧牲完整性(最好留作參考)和(有時)嚴格的準確性。這并不是說概念性文件應該故意不準確;這只是意味著它應該關注常見的用法,而將罕見的用法或副作用留作參考文檔。
05
文檔Review
在一個組織內,光靠個人去維護文檔是不行的,必須得借助群體的智慧。在一個組織內部,文檔的變更也應該像代碼的變更一樣,需要被其他人Review,以提前發現其中的問題并提升文檔的質量。技術文檔得益于三種不同類型的review,每種審查都強調不同的方面:
專業的視角來保證準確性:一般由團隊里比較資深的人負責,他們關注的核心點是文檔寫的對不對,專不專業。如果Code Review做的好的話,文檔的Review也屬于Code Review的一部分。
讀者視角保證簡潔性:一般由不熟悉這個領域的人來Review,比如團隊的新人,或者文檔的使用者。這部分主要是關注文檔是否容易被看懂。
寫作者視角保證一致性:由寫作經驗豐富或者相關領域比較資深的人承擔,主要是為了保證文檔前后是否一致,比如對同一個專業術語的使用和理解是否有歧義。
06
文檔寫作的哲學
下面的部分更多地是關于技術寫作最佳實踐的論述。5W法則相信大家已經聽的多了,分別是WHO, WHAT, WHEN, WHERE, WHY,這是一個廣泛被用在各行各業的法則,寫文檔當然也不例外。WHO:正如前面所說,文檔的針對對象是誰,讀者是誰。
WHAT:明確文檔寫作的用途,通常僅需說明文檔的用途和目的就能幫你搭建起整個文檔的框架。
WHEN:明確文檔的創建、Review和更新日期。因為文檔也有時效性,明確相關日期可以避免閱讀者踩坑。
WHERE:文檔應該放在哪!建議一個組織或者團隊有統一的永久文檔存放地址,并且有版本控制。最好是方便查找、使用和分享。
WHY:為什么要寫這篇文檔, 你期望讀者讀完后從文檔中獲得什么!
1.三段式文檔
所有文檔,文檔的所有部分都有開頭、中間和結尾。盡管這聽起來非常愚蠢,但大多數文件通常都應該有這三個部分。不要害怕在文檔中添加章節;它們將流程分解為邏輯部分,并為讀者提供文檔所涵蓋內容的路線圖。
通常開頭部分代表問題,中間部分介紹推薦的解決方案,結尾部分總結結論。但這也并不以為著文檔應該有三個部分,如果文檔內容比較多,可以將其做更細致的拆解,可以適當增加一些冗余的信息幫助讀者理解文檔內容。雖然很多工程師都討厭冗余 極力追求簡潔,但寫文檔和寫代碼不同,適當的冗余反而可以幫助讀者理解。
2.好文檔必備的屬性
好的文檔通常有三個方面:完整性、準確性和清晰度。很少在同一個文檔中同時獲得這三種信息;例如,當你試圖使文檔更完整時,清晰度就會開始受到影響。如果您試圖記錄API的每個可能的用例,您可能會得到一個難以理解的混亂。對于編程語言來說,在所有情況下都做到完全準確(并記錄所有可能的副作用)也會影響清晰度。對于其他文件,試圖明確一個復雜的主題可能會微妙地影響文件的準確性;例如,您可能決定忽略概念性文檔中的一些罕見的副作用,因為文檔的目的是讓人們熟悉API的用法,而不是提供對所有預期行為的武斷概述。
在每種情況下,一個好的文檔都被定義為正在執行其預期工作的文檔。因此,您很少希望文檔執行一項以上的工作。對于每個文檔(以及每個文檔類型),確定其重點并適當調整編寫,寫概念性文檔可能不需要涵蓋API的每個部分,寫一個參考可能想要這個完整,但可能必須犧牲一些清晰度等。所有這些加起來就是質量,不可否認的是,質量很難精確衡量。
07
結論
公平地說,對文檔的處理與對測試的處理并不一定相同。對測試來講可以進行原子測試(單元測試),并遵循規定的形式和功能。在大多數情況下,文件不能。測試可以自動化,但通常缺乏自動化文檔的方案。文件必然是主觀的;文檔的質量不是由作者來衡量的,而是由讀者來衡量的,而且通常是異步的。
最后總結下本文幾個關鍵點:
隨著時間推移,團隊的壯大,文檔會越來越重要;
文檔應該是開發人員工作流程的一部分;
每篇文檔專注于一個目的;
文檔是給讀者看的,而不是你自己寫作。
責任編輯:haq
-
工程師
+關注
關注
59文章
1571瀏覽量
68574 -
代碼
+關注
關注
30文章
4809瀏覽量
68823
原文標題:如何寫好技術文檔?
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論