如何解決代碼和文檔不一致的問題?
這裡的文檔指的不是Javadoc、Doxygen等生成的API文檔。對於負責任的團隊來說這類文檔的更新是可以保證在修改代碼的同時進行更新的。比較麻煩的是類似於Programming Guide、Tutorial等性質的文檔。這類文檔是單獨撰寫的,並不包含在程序源碼內。後續修改代碼時,程序員甚至根本不知道正被修改的這段代碼邏輯在某篇文檔的某個犄角旮旯里的被引用過,自然也想不到去更新。對於平台類的軟體,這類問題尤為重要。請問這類問題如何解決?
軟體技術一直在進步,但我們怎麼構造軟體的過程的討論,卻似乎一直在原地踏步,你會發現很多問題和辯論從多年前開始就有,現在還有,代碼和文檔的衝突就是其中一個。
單就命題來看,是希望能有解決代碼和文檔的映射關係問題。根據自身在公司的項目經驗,這不能說一件無法實現的問題,但至少沒那麼容易。開發者足夠的耐心(涉及工具和心理負擔,如鄒老師所述),投入的時間成本(客戶是不是能夠承受文檔和代碼同步進行所帶來的開發進度變慢),更重要的是可維護性(文檔編撰者的移情能力,以及後續維護者的理解力),都會挑戰文檔和代碼的匹配程度。
事實也證明,大多數這樣底層的技術文檔最後都會變成垃圾,變成後續開發維護者理解的障礙和鄙視前人的依據。即便是自動生成的API文檔,也大多會流於形式少有人參考,像MSDN那樣的畢竟太少了。
所以這個問題不是不能解決,只是成本很高。我們更希望開發者能以代碼為理解系統行為的主要依據,用系統和代碼的真實行為作為實踐的依據,以這個為前提,如何構造出更易讀易理解的代碼結構才是相對編撰「完美」文檔更有價值的事情。換個角度看,好的開發者會閱讀代碼而不是依賴文檔來確信自己了解系統的行為。
技術文檔不是沒有價值和存在的必要,相反,它應該更多聚焦在:
- 重要的技術架構、代碼結構和解決方案上
- 難理解的演算法結構上
這些東西基本只能靠老闆的命令
Programming Guide、Tutorial一般都是針對介面的,而介面是相對穩定的,所以這個應該不是問題吧?至於那種對應到行的文檔, @張凱峰 的答案中已經說的很清楚了,這樣的文檔實用價值較低,一般情況不值得花大力氣維護。更好的替代解決方案是編寫能夠自解釋的代碼。雖然這對於開發人員的素質要求較高,但是相對來說比其它文檔同步的方案都要好。
再次引用@張凱峰 的答案,技術文檔應該關註:- 重要的技術架構、代碼結構和解決方案上
- 難理解的演算法結構上
改動者要知會負責文檔的人/團隊,配合更新文檔,改動者也要review更改後的文檔。這些全部可以用工作流程規範化。而文檔作為項目發布的一部分,需要更新完備及齊全才能正式發布新版本。
問題主要是公司/團隊怎樣看代文檔的重要性。
和項目的類型有關,如果項目是探索為主,那麼不必拘泥於文檔的一致性;如果項目是有重要的經濟和法律後果,那麼文檔必須如實反映代碼的真實情況。
文檔保存之後一分鐘,就開始逐漸失效
① 文檔真正表述只有文檔才適合表述的內容。 如果一些規則和要求是可以量化的,可以測量的,那麼就把它們變成單元測試和模塊測試的一部分。(例如:某地理信息系統的各個實體的包含關係不會出現循環包含的情況;某個資料庫的某欄位內容不能是另一個內容的真子集;某個API 會被 3 個不同子程序調用因此不能單方面修改) 這樣一旦出現不一致, 就可以立即發現。 這些信息不必很詳細地寫在文檔中 -- 因為文檔根本沒有邏輯約束力。
② 用工具把文檔綁定在團隊的業務活動中。 文檔通常散落在某子目錄下,或某冗長的SharePoint 路徑下,沒有人會想起去維護。 可以把文檔放到項目管理系統中 (例如TFS),當更新某模塊或測試用例的時候,項目管理流程就會要求更新文檔。 如果文檔非常重要,可以在代碼複審的同時複審文檔。 文檔的檢查也可以放在項目發布的 check-list 中。
③ 把維護文檔的實際負擔和心理負擔降低。 比如用輕量的wiki 來維護,不要求員工寫精美格式的文檔。
Github創始人Tom Preston-Werner,在開源社區主張這樣一種文檔的思想:
對於程序員來說,就算文檔寫的再好再全,不看到源碼還是無法徹底放心使用介面。所以與其費盡心機的在源碼外的某處撰寫和維護文檔,還不如將文檔和源碼結合起來,也就是把源碼中的comment系統化規範化成文檔的形式。
在這個思想下,他創造了一種叫tomdoc的ruby源碼文檔規範:TomDoc 1.0.0-rc1
寫法和規則其實都很簡單,最大的好處在於維護代碼的同時就能完成文檔的維護,而文檔和源碼一體化也滿足很多程序員的習慣。統一了語法的commenting內容也可以很容易的使用第三方工具來提取,然後生成單獨成冊的文檔供網頁使用。感興趣的朋友可以去github搜索一下,這個文檔規範在開源社區的使用者不少,而且也很容易作出適用於其他語言的版本。
-------------------
另外一個思想類似,但有更完整配套方案的文檔gem叫YARD:YARD - A Ruby Documentation Tool這個也有其他語言的版本,可以自行搜索。個人認為這種文檔記錄方式應該是更人性化和高效率的,當然適用範圍目前來說還是開源社區,至於閉源軟體和面向非開發者的文檔就是另一回事了。無解rtfc
然後有空就update, 沒空就繼續留著坑.
文檔很多類:
1. 題主問的那種Tutorial、Programming Guide,這類對外的文檔(用戶、外部開發者,一般是指導性的)
2. 從代碼注釋中由軟體生成的,一般是API Guide文檔(對內對外都有價值,可能不會對外公開)
3. 內部開發資料、參考資料(一般對內,開源項目也一般以wiki的形式公開)
等等
---------------
首先,題主說的這些文檔(第1類)是產品的一部分,很多項目都把這些文檔的源碼(比如markdown源碼、tex源碼等)與產品代碼放到同一代碼庫中(例如分別放置到doc和src目錄),並且將編譯文檔的命令寫進build/make腳本中,使得它們可以與整個產品一同或者獨立構建,而且一般也有版本號的概念與產品的版本號相同。
其次,不同的文檔,受眾和重要程度不同,例如:Tutorial/User Guide是給產品的用戶看的,這個一般都會有;而Programming Guide/Developer Guide則是給產品的開發者看的,如果這個產品不是一個開源項目,或者開放的可以讓其他開發者參與進來二次開發的項目,則這部分可以考慮作為內部培訓資料提供,而不用花太大的精力將其作為產品的一部分更新。
明確了這些,那麼每個(對外發布的)版本的開發周期進入到API freeze/feature freeze/beta/rc等相應階段時,由專人,或者由代碼開發人員抽時間,進行對應文檔的review、update。既然作為產品的一部分,那麼如果用戶群大、項目靠譜,我覺得這類文檔也得經過QA。
這與從代碼中生成的doc(第2類)不同,前者(第1類)不需要與代碼實時同步,只需要針對每個發布版本更新,變動的周期不會很短。
而對於內部開發資料(第3類)則可以更隨意一些,放到wiki裡面,明確註明更新日期、針對版本即可,開發者需要時或者有空時隨手一改,查閱時若發現時間、版本不對也可以多留個心眼以免被過期文檔誤導。
我覺得這類文檔應該不會被頻繁修改,屬於大方向上的問題,如果代碼總得方向都變了,還不如從新寫這類文檔,然後給出變動理由,舊文檔就放在那裡共後人參考
如何解決代碼和文檔不一致的問題?我的感覺是無解…廢掉老舊無用的文檔,或者在修改代碼的時候,隨時修改文檔,記得及時備份。
這類問題文檔僅僅具有參考價值,不可全信。有時候還會起到誤導的作用。只能靠程序員閱讀源代碼去重新update 文檔了。
推薦閱讀:
※為什麼word文檔會比txt文檔大?
※在github上弄一個vscode說明文檔的翻譯項目,集大家的力量完成,這麼做是否有意義?
※有沒有可以內置tex公式編輯且能將文本轉成pdf的markdown編輯器?
※Adobe Photoshop 里文字編輯時能否自動換行?
※如何編輯PDF格式文檔?