您好,登錄后才能下訂單哦!
本文首發于 vivo互聯網技術 微信公眾號
鏈接: https://mp.weixin.qq.com/s/VWjB83NBTg6FwPBDg8G0HQ
作者:Shi Zhengxing
本文對自己工作中碰到的大量日常咨詢進行經驗總結,說明一款開發框架文檔應該要寫哪些內容。從 功能框架、 特性使用流程、 功能描述三個維度說明文檔編寫的邏輯性。希望能給同樣從事開發框架的開發與維護的同行帶來一點啟發。
曾經有一段較為短暫的時間,接手了超過10個開發框架的日常維護,其中大部分還是處于活躍的開發迭代狀態。平均下來,那段時間可能每周都有那么一天會被內部即時通訊軟件不停打斷以至于無法進入既定的工作任務中去,一旦碰到三兩個非常棘手,排查起來非常耗時的支持或者問題時,那一周的產出就會比較低了。
有人會說,你不能集中去回答用戶的咨詢嗎?答案是最好不要,因為我們把用戶滿意度放在很重要的位置,回復的及時性無疑對用戶滿意度有重要影響。
經過對問題的總結歸類:
(1)第一類約占40%的日常支持,是關于在某個特定的場景下如何使用這個開發框架(因為接手維護時用戶使用文檔結構混亂,難以在文檔中快速找到想要的內容,或者根本就沒有這部分內容,用戶只能電話咨詢或者面詢);
(2)第二類約占30%的是使用過程中出現了預期外的狀況,需要幫助定位排查問題;
在多次的思考與總結后,我認為這里面有很大的優化空間,按照我的想法對文檔進行優化落地后,預估每周能為我節省出接近1天的時間,接下來我將介紹我的想法及實踐經驗。
下面我分別給出理想狀態(下圖左)與現實狀態(下圖右)下,文檔、框架開發者、框架使用者之間的關系。
(圖一)
從圖中可以看出,理想狀態下,開發者只需通過文檔向使用者傳遞信息,實際上很多開源框架在使用的時候也是如此,雖然使用者還是具備與開發者溝通的渠道(例如郵件或者github的issue),但是那是低頻的。現實情況下,大公司內部的基礎開發框架不僅要編寫文檔,還需要不停與內部使用者進行多種類多渠道的溝通。
為了能讓大家大致理解這是什么樣的溝通,以及我面臨的文檔方面的問題,這里我將過往真實案例,稍作修飾——以期達到較少的案例抽象出較多的問題——陳述如下。
一個老員工希望使用熔斷框架保護自己的系統,通過自己保存的我們團隊的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連接生命周期狀態轉化圖:
(圖五)
在功能流程邏輯中有寫到,流程中的每一個步驟,都要寫清楚相應的細節,通過文檔的不斷更新迭代來完善。這里如何把這些細節有條理、完整的描述清楚,需要注意以下幾點:
最后,要意識到每個人的思維方式、邏輯習慣是有差異的,無論花多少心思去寫文檔,都難以做到十全十美不遺漏無疏忽,因此還需要一個用戶反饋的渠道,例如大多數文檔系統都有評論功能。下圖是文檔聯系起使用者與開發者后的成熟態。
(圖六)
文檔編寫的基本目的,是幫助使用者來使用框架,但是不能忽略的是,框架的開發者也是文檔的重要用戶,文檔在方便用戶的同時,也要方便自己。
本文從日常咨詢存在的問題引發出思考,聯想到文檔也是一個產品,用來解決特定人群的問題。因為不懂產品,不能從產品的專業角度對文檔進行解構,只能根據自己經驗說明文檔應該要寫哪些內容,從功能框架、特性使用流程、功能描述時注意事項等說明了文檔編寫的邏輯性。希望對同樣從事開發框架的開發與維護的同行一點啟發。
作為框架的開發者,用戶的肯定與點贊是我們最好的回報。我們會注重編碼質量,但是往往忽略文檔的重要性,框架很牛逼但是文檔寫得很爛,用戶用起來不順暢,會讓框架的價值大打折扣。意識到這一點很重要,寫出牛逼的代碼,文檔也寫得清晰易讀,用戶才會覺得框架牛逼,順帶才會認為作者牛逼。牛逼的事情做多了,你的技術影響力自然就上來了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。