本文首發於 vivo互聯網技術 微信公衆號
連接: https://mp.weixin.qq.com/s/VWjB83NBTg6FwPBDg8G0HQ
做者:Shi Zhengxing
本文對本身工做中碰到的大量平常諮詢進行經驗總結,說明一款開發框架文檔應該要寫哪些內容。從功能框架、特性使用流程、功能描述三個維度說明文檔編寫的邏輯性。但願能給一樣從事開發框架的開發與維護的同行帶來一點啓發。java
曾經有一段較爲短暫的時間,接手了超過10個開發框架的平常維護,其中大部分仍是處於活躍的開發迭代狀態。平均下來,那段時間可能每週都有那麼一天會被內部即時通信軟件不停打斷以致於沒法進入既定的工做任務中去,一旦碰到三兩個很是棘手,排查起來很是耗時的支持或者問題時,那一週的產出就會比較低了。git
有人會說,你不能集中去回答用戶的諮詢嗎?答案是最好不要,由於咱們把用戶滿意度放在很重要的位置,回覆的及時性無疑對用戶滿意度有重要影響。程序員
通過對問題的總結歸類:github
(1)第一類約佔40%的平常支持,是關於在某個特定的場景下如何使用這個開發框架(由於接手維護時用戶使用文檔結構混亂,難以在文檔中快速找到想要的內容,或者根本就沒有這部份內容,用戶只能電話諮詢或者面詢);redis
(2)第二類約佔30%的是使用過程當中出現了預期外的狀況,須要幫助定位排查問題;spring
在屢次的思考與總結後,我認爲這裏面有很大的優化空間,按照個人想法對文檔進行優化落地後,預估每週能爲我節省出接近1天的時間,接下來我將介紹個人想法及實踐經驗。json
下面我分別給出理想狀態(下圖左)與現實狀態(下圖右)下,文檔、框架開發者、框架使用者之間的關係。安全
(圖一)微信
從圖中能夠看出,理想狀態下,開發者只需經過文檔向使用者傳遞信息,實際上不少開源框架在使用的時候也是如此,雖然使用者仍是具有與開發者溝通的渠道(例如郵件或者github的issue),可是那是低頻的。現實狀況下,大公司內部的基礎開發框架不只要編寫文檔,還須要不停與內部使用者進行多種類多渠道的溝通。mybatis
爲了能讓你們大體理解這是什麼樣的溝通,以及我面臨的文檔方面的問題,這裏我將過往真實案例,稍做修飾——以期達到較少的案例抽象出較多的問題——陳述以下。
一個老員工但願使用熔斷框架保護本身的系統,經過本身保存的咱們團隊的wiki主頁連接找到了熔斷框架的文檔連接,花了15分鐘認真仔細看徹底部文檔後,不太肯定爲啥要用咱們團隊提供的熔斷框架,而不直接用開源的,他沒有多想,直接按照文檔描述寫了個demo,最終跑起來了;
接着準備正式應用在業務代碼上,他從文檔上了解到可能須要根據本身業務狀況調整一些初始化參數,可是由於參數說明很簡單,之前也沒有使用過熔斷框架,加上領域知識專業性較強,看了基本不理解具體能達到什麼效果,就準備打電話過來諮詢下,因而他看到文檔的建立人和最近修改人不是同一我的,猶豫了一下,他給最近修改人打了電話。
一個南京的有多年java開發經驗的同窗,接手了一個有較大數據量的開發任務;因爲前面參加了vivo內部基於spirng boot的腳手架(下文簡稱腳手架)培訓分享,從ppt裏找到咱們的項目網站,並下載了工程,嘗試性的從wiki上搜索,找到了咱們的文檔「使用腳手架快速集成vivo-mybatis」,看完文檔後仍是不肯定他的分庫分表之單庫多表場景是否支持,因而他打電話過來諮詢;諮詢完確認支持並瞭解單庫多表與多庫多表的配置差別後,他在mybatis的配置文件中加上了分庫分表的插件,可是文檔沒有介紹分庫分表的原理,也沒有單庫多表的配置示例,試了好幾回都不行,最後他反編譯後看了框架部分源碼後明確了配置方式,問題都解決了,可是花費了較大精力。
一個同事在wiki上搜索到了2個關於spring boot工程接入vivo配置中心的文檔,是由不一樣的人編輯維護的,不知道該以哪一個文檔爲準,因而打電話其中一我的反饋了這個狀況。後面兩個文檔的編寫者驗證狀況屬實,須要合併,可是難以決定合併後的文檔放到配置中心用戶文檔目錄下仍是放到腳手架用戶文檔目錄下。
問題1:文檔入口須要口口相傳;若是沒有保存這個連接信息,那就要從其餘同事那裏詢問。
問題2:文檔內容存在缺漏,用戶短期就能夠看完全部的文檔,而且沒有按照功能特性進行分類,須要看所有文檔。
問題3:沒有作競品分析,沒有明確介紹內部框架與開源同類框架到底有什麼差別。
問題4:框架配置參數說明過於簡單,沒有相應的領域知識介紹,用戶看不明白或者不理解。
問題5:維護的基於開源的基礎框架,沒有根據公司開發環境進行定製優化,須要調整參數後才能使用上線。
問題6:框架當前的owner從用戶角度來講不清晰。
問題1:項目網站地址要人爲單獨記憶,宣傳難度極大。
問題2:框架文檔沒有作到能輕易獲取,須要用戶嘗試不肯定性搜索。
問題3:用戶須要打電話詢問是否支持他的場景,說明這個文檔沒有準確描述支持哪些場景,有遺漏,也沒有把相關場景下的demo示例給出來。
問題4:框架在打包的時候,沒有打源碼包。
問題5:文檔缺少對實現原理的介紹。
問題1:多個文檔說一件事情,說明文檔存在混亂的狀況。
問題2:文檔歸屬到哪一個模塊難以達成一致,說明沒有站在用戶角度去劃歸職責。
本文到如今爲止,描述的關於文檔的問題以及這些問題出如今什麼場景下,已經清晰的浮現於眼前了。可是咱們在寫文檔以前,得先有一個判斷標準,怎樣的文檔纔算是好的文檔呢?我認爲答案很簡單,就是隻要能減小使用者與開發者間的溝通,只要能提高溝通效率,無限靠近圖一中所示的理想狀態,那麼這個框架的用戶文檔就算是好的文檔。因此你看,文檔也是用來解決某個問題的,它能夠被視做一款獨立的產品。文檔該寫什麼,也就是這個產品應該有什麼功能。
接下來咱們對文檔這款產品進行產品關鍵特性分析:
根據本身的過往經驗,結合上述產品關鍵特性分析,我認爲完整的框架文檔應當包含如下分類的內容。
由於不一樣框架的文檔各個部分的重要性會有所差別,所以以上分類的描述篇幅、呈現方式、內容載體,會有很大差別,下圖是咱們團隊開發的分佈式鎖框架基於wiki呈現方式的文檔目錄。前面的序號是爲了方便與用戶基於文檔的溝通(與用戶的直接溝通是難以免的)。
(圖二)
看完上面示例圖後,理解會稍微直觀點,接下來我將上面的6種較爲抽象的分類,細化成具體的wiki的功能頁面,固然這只是示例性的:
(1)框架首頁:對當前框架進行概述性描述,好比宣傳標語,具有的功能特性,能解決什麼問題,使用場景;下一步引導,社區引導;若是是基於開源版本開發,也能夠在此介紹在開源版本基礎上作了什麼;若是不是,最好能類比下開源同類產品(競品分析);還能夠有核心指標,用以展現競爭力和受歡迎程度,提高用戶的使用信心。
(2)領域知識:目標爲讓用戶的相關知識水平與你貼近,讓用戶理解你的行爲與作法,提高用戶承認度或者滿意度。
(3)快速開始:只有最小依賴下的簡單場景的快速接入及使用描述,用戶拷貝上面的代碼便可直接運行,同時描述如何得到它。此處也應該給出示例的demo獲取方式。
(4)依賴與限制:描述當前框架運行的依賴項,包含運行環境依賴,maven必須依賴與選擇依賴列表(例如dubbo使用zookeeper與使用nacos做爲註冊中心的依賴項有差別),依賴的中間件或者業務系統;限制信息好比不能使用fastjson做爲json工具,必須使用cluster模式的redis集羣等。
(5)配置項:詳細描述每個配置的使用方法,起到什麼做用,注意事項,配置key最好有必定設計邏輯,方便理解。
(6)詳細使用說明:綜合性的用戶文檔,針對全部的能力特性如何使用,進行描述說明,須要說明所有細節。
(7)多場景使用示例:從用戶各類不一樣的使用場景出發,給出配置/示例代碼,同時給出下載導入IDE便可運行的demo,方便不一樣需求的用戶來閱讀。
(8)版本發佈記錄:用於追溯、記錄版本的發佈時間、變更內容。
(9)升級指導:用於指導用戶如何升級版本。
(10)設計及原理:包含各類類型的設計文檔、原理說明、源碼導讀。幫助深度用戶瞭解運行原理,爲源碼閱讀提供必定的指導;也須要說明設計時遵循了什麼規範,幫助用戶識別底層特性。
(11)質量信息:功能測試報告、性能測試報告、漏洞掃描報告、遵循的標準化規範。
(12)FAQ:能夠在此頁面概括整理較爲典型的/常見的用戶疑問,方便其餘有相似疑問的同事看(相似最佳實踐),減小溝通工做量。須要注意的是,此處只是臨時性的公共問題導引地址,從長遠看,用戶常問的問題須要從系統設計層面進行優化,或者要在詳細使用說明處進行顯著提示。
文檔的閱讀者通常是程序員,程序員的思惟邏輯性較強,所以咱們寫出來的文檔具有較強的邏輯性是基礎要求,如下從三個維度來描述文檔的邏輯性。
文檔的總體邏輯建議依據上面的6個分類內容進行「總-分-總」式編寫。首先要對框架進行總體介紹,這個能夠放到框架首頁,接着明確要輸出文檔的類別(按照框架的不一樣能夠選擇性的寫對應類別的文檔,固然不是必定要輸出所有6個類別的文檔)及對框架功能特性進行枚舉,這是一個「總-分」的過程。接着能夠將單個類別的文檔或者單個特性的說明文檔做爲獨立的模塊,進行詳細說明。另外,用戶查看頻率較高的部分,也應該添加菜單單獨編寫,方便用戶快讀查找瀏覽。咱們看下分佈式鎖框架文檔的主頁:
(圖三)
單個類別的文檔在編寫的時候,也須要視具體內容的複雜度,屢次進行「總-分」形式的拆分。屢次拆分後通常須要再次「總」的過程,來組合成一個完整的功能特性。
在圖二分佈式鎖框架的文檔目錄中,從功能框架邏輯上來講,「依賴與限制」內容雖然也會比較少,可是通常在使用一個框架的時候是必看的內容,所以這裏將其做爲獨立的模塊。「快速開始」顧名思義就是引導用戶快速瞭解框架,很是重要,注意要以最簡潔的話語、最簡的配置、最少的代碼、最少的依賴,以最小的篇幅來進行說明,目標是2分鐘內能看懂。「配置手冊」固然是羅列的所有的框架配置相關,包含功能、性能的調節參數,還要注意將經常使用配置與不經常使用的分開,總之一個原則,保持全面完整可是也要按使用頻次歸類。「詳細說明」主要從用戶接入、使用、調優、注意事項等角度,對框架進行全方位的說明,通常會佔有最大的篇幅。「多場景demo示例」建議枚舉用戶全部的使用場景,針對場景提供示例代碼。「版本與升級」其實就是發佈與變動日誌,版本兼容性說明,相應的用戶的升級注意事項。
以下爲咱們團隊開發的分佈式鎖框架」詳細說明「頁面的目錄:
(圖四)
功能流程邏輯能夠理解爲一個功能使用時的多個具體步驟的串聯。例如使用分佈式鎖框架的典型步驟以下:
經過maven依賴分佈式鎖框架jar包->配置zookeeper或者redis的地址->編碼(獲取鎖)->編碼(釋放鎖)
這個過程這麼寫你們會不會以爲就很明白也很不明白?雖然總體流程是很簡單,可是文檔毫不能夠只是寫這些內容,不然會給開發者帶來無盡的用戶溝通。例如文檔還應當包含:指明某個功能最低版本(依賴什麼版本的包合適),spring環境、spring boot環境、純java環境如何依賴,依賴的三方包衝突範圍及排查方法,zookeeper配置參數以及集羣可用性與框架穩定性說明,zookeeper鏈接管理說明,鎖獲取與釋放過程可重入性說明,異常處理指導,最佳實踐等等,這仍是API最基本的使用方式,換作是註解的使用方式,須要說明的細節就更多了。至於應該寫清楚哪些細節,能夠是逐漸完善的,文檔也是須要不斷迭代更新的。
爲了用戶好閱讀,建議以流程圖的形式,分使用場景逐個進行說明。每一個步驟要將相關的細節說清楚,避免用戶使用過程的電話溝通確認。
在進行框架原理或者源碼的描述時,時常涉及到狀態變化描述、生命週期描述等等,顯然使用常規流程圖不足以表達清晰,此時換作狀態轉化圖、時序圖、加上了泳道的流程圖,效果會更好。咱們看下TCP鏈接生命週期狀態轉化圖:
(圖五)
在功能流程邏輯中有寫到,流程中的每個步驟,都要寫清楚相應的細節,經過文檔的不斷更新迭代來完善。這裏如何把這些細節有條理、完整的描述清楚,須要注意如下幾點:
最後,要意識到每一個人的思惟方式、邏輯習慣是有差別的,不管花多少心思去寫文檔,都難以作到十全十美不遺漏無疏忽,所以還須要一個用戶反饋的渠道,例如大多數文檔系統都有評論功能。下圖是文檔聯繫起使用者與開發者後的成熟態。
(圖六)
文檔編寫的基本目的,是幫助使用者來使用框架,可是不能忽略的是,框架的開發者也是文檔的重要用戶,文檔在方便用戶的同時,也要方便本身。
本文從平常諮詢存在的問題引起出思考,聯想到文檔也是一個產品,用來解決特定人羣的問題。由於不懂產品,不能從產品的專業角度對文檔進行解構,只能根據本身經驗說明文檔應該要寫哪些內容,從功能框架、特性使用流程、功能描述時注意事項等說明了文檔編寫的邏輯性。但願對一樣從事開發框架的開發與維護的同行一點啓發。
做爲框架的開發者,用戶的確定與點贊是咱們最好的回報。咱們會注重編碼質量,可是每每忽略文檔的重要性,框架很牛逼可是文檔寫得很爛,用戶用起來不暢,會讓框架的價值大打折扣。意識到這一點很重要,寫出牛逼的代碼,文檔也寫得清晰易讀,用戶纔會以爲框架牛逼,順帶纔會認爲做者牛逼。牛逼的事情作多了,你的技術影響力天然就上來了。
更多內容敬請關注vivo 互聯網技術微信公衆號
注:轉載文章請先與微信號:Labs2020聯繫。