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