開發框架文件體系化的思考

vivo網際網路技術發表於2020-06-15
本文首發於 vivo網際網路技術 微信公眾號
連結: https://mp.weixin.qq.com/s/VWjB83NBTg6FwPBDg8G0HQ ​​​​​​​
作者:Shi Zhengxing

本文對自己工作中碰到的大量日常諮詢進行經驗總結,說明一款開發框架文件應該要寫哪些內容。從功能框架特性使用流程功能描述三個維度說明文件編寫的邏輯性。希望能給同樣從事開發框架的開發與維護的同行帶來一點啟發。

一、前言

曾經有一段較為短暫的時間,接手了超過10個開發框架的日常維護,其中大部分還是處於活躍的開發迭代狀態。平均下來,那段時間可能每週都有那麼一天會被內部即時通訊軟體不停打斷以至於無法進入既定的工作任務中去,一旦碰到三兩個非常棘手,排查起來非常耗時的支援或者問題時,那一週的產出就會比較低了。

有人會說,你不能集中去回答使用者的諮詢嗎?答案是最好不要,因為我們把使用者滿意度放在很重要的位置,回覆的及時性無疑對使用者滿意度有重要影響。

經過對問題的總結歸類:

(1)第一類約佔40%的日常支援,是關於在某個特定的場景下如何使用這個開發框架(因為接手維護時使用者使用文件結構混亂,難以在文件中快速找到想要的內容,或者根本就沒有這部分內容,使用者只能電話諮詢或者面詢);

(2)第二類約佔30%的是使用過程中出現了預期外的狀況,需要幫助定位排查問題;

在多次的思考與總結後,我認為這裡面有很大的優化空間,按照我的想法對文件進行優化落地後,預估每週能為我節省出接近1天的時間,接下來我將介紹我的想法及實踐經驗。

二、問題定義及我的思考

1、問題描述

下面我分別給出理想狀態(下圖左)與現實狀態(下圖右)下,文件、框架開發者、框架使用者之間的關係。

(圖一)

從圖中可以看出,理想狀態下,開發者只需通過文件向使用者傳遞資訊,實際上很多開源框架在使用的時候也是如此,雖然使用者還是具備與開發者溝通的渠道(例如郵件或者github的issue),但是那是低頻的。現實情況下,大公司內部的基礎開發框架不僅要編寫文件,還需要不停與內部使用者進行多種類多渠道的溝通。

為了能讓大家大致理解這是什麼樣的溝通,以及我面臨的文件方面的問題,這裡我將過往真實案例,稍作修飾——以期達到較少的案例抽象出較多的問題——陳述如下。

1.1、案例一

一個老員工希望使用熔斷框架保護自己的系統,通過自己儲存的我們團隊的wiki主頁連結找到了熔斷框架的文件連結,花了15分鐘認真仔細看完全部文件後,不太確定為啥要用我們團隊提供的熔斷框架,而不直接用開源的,他沒有多想,直接按照文件描述寫了個demo,最終跑起來了;

接著準備正式應用在業務程式碼上,他從文件上了解到可能需要根據自己業務情況調整一些初始化引數,但是因為引數說明很簡單,以前也沒有使用過熔斷框架,加上領域知識專業性較強,看了基本不理解具體能達到什麼效果,就準備打電話過來諮詢下,於是他看到文件的建立人和最近修改人不是同一個人,猶豫了一下,他給最近修改人打了電話。

1.2、案例二

一個南京的有多年java開發經驗的同學,接手了一個有較大資料量的開發任務;由於前面參加了vivo內部基於spirng boot的腳手架(下文簡稱腳手架)培訓分享,從ppt裡找到我們的專案網站,並下載了工程,嘗試性的從wiki上搜尋,找到了我們的文件“使用腳手架快速整合vivo-mybatis”,看完文件後還是不確定他的分庫分表之單庫多表場景是否支援,於是他打電話過來諮詢;諮詢完確認支援並瞭解單庫多表與多庫多表的配置差異後,他在mybatis的配置檔案中加上了分庫分表的外掛,但是文件沒有介紹分庫分表的原理,也沒有單庫多表的配置示例,試了好幾次都不行,最後他反編譯後看了框架部分原始碼後明確了配置方式,問題都解決了,但是花費了較大精力。

1.3、案例三

一個同事在wiki上搜尋到了2個關於spring boot工程接入vivo配置中心的文件,是由不同的人編輯維護的,不知道該以哪個文件為準,於是打電話其中一個人反饋了這個情況。後面兩個文件的編寫者驗證情況屬實,需要合併,但是難以決定合併後的文件放到配置中心使用者文件目錄下還是放到腳手架使用者文件目錄下。

2、問題總結

2.1、案例一問題識別

問題1:文件入口需要口口相傳;如果沒有儲存這個連結資訊,那就要從其他同事那裡詢問。

問題2:文件內容存在缺漏,使用者短時間就可以看完所有的文件,並且沒有按照功能特性進行分類,需要看全部文件。

問題3:沒有做競品分析,沒有明確介紹內部框架與開源同類框架到底有什麼差異。

問題4:框架配置引數說明過於簡單,沒有相應的領域知識介紹,使用者看不明白或者不理解。

問題5:維護的基於開源的基礎框架,沒有根據公司開發環境進行定製優化,需要調整引數後才能使用上線。

問題6:框架當前的owner從使用者角度來說不清晰。

2.2、案例二問題識別

問題1:專案網站地址要人為單獨記憶,宣傳難度極大。

問題2:框架文件沒有做到能輕易獲取,需要使用者嘗試不確定性搜尋。

問題3:使用者需要打電話詢問是否支援他的場景,說明這個文件沒有準確描述支援哪些場景,有遺漏,也沒有把相關場景下的demo示例給出來。

問題4:框架在打包的時候,沒有打原始碼包。

問題5:文件缺乏對實現原理的介紹。

2.3、案例三問題識別

問題1:多個文件說一件事情,說明文件存在混亂的情況。

問題2:文件歸屬到哪個模組難以達成一致,說明沒有站在使用者角度去劃歸職責。

三、框架文件該寫什麼

1、外行說產品

本文到現在為止,描述的關於文件的問題以及這些問題出現在什麼場景下,已經清晰的浮現於眼前了。但是我們在寫文件之前,得先有一個判斷標準,怎樣的文件才算是好的文件呢?我認為答案很簡單,就是隻要能減少使用者與開發者間的溝通,只要能提升溝通效率,無限靠近圖一中所示的理想狀態,那麼這個框架的使用者文件就算是好的文件。所以你看,文件也是用來解決某個問題的,它可以被視作一款獨立的產品。文件該寫什麼,也就是這個產品應該有什麼功能。

接下來我們對文件這款產品進行產品關鍵特性分析:

  • 核心使用者:框架使用者;
  • 剛性需求:基於文件的幫助,快速並順暢的使用框架;
  • 典型場景:通過閱讀框架文件,完成接入、使用、調優、問題排查等日常開發流程;
  • 產品概念:避免或者減少框架使用者與開發者頻繁的直接溝通,再不濟也要提升溝通效率,讓使用者更加順暢的使用,同時將開發者從大量的日常支援中解放出來;
  • 競品調研:可調研dubbo、spring的使用者文件

2、文件應當包含哪些內容

根據自己的過往經驗,結合上述產品關鍵特性分析,我認為完整的框架文件應當包含以下分類的內容。

  1. 背景及領域相關知識(介紹背景、基礎原理、領域相關知識、專有名詞,將部分使用者的知識水平儘量拉抬到開發者相同層次)
  2. 適用場景,以及場景對應的依賴與限制
  3. 接入、使用、調優相關
  4. 質量資訊(功能測試、效能測試、安全性相關)
  5. 使用者習慣培養(建議、知識分享、注意事項)
  6. 架構設計與原始碼閱讀指引

因為不同框架的文件各個部分的重要性會有所差異,因此以上分類的描述篇幅、呈現方式、內容載體,會有很大差異,下圖是我們團隊開發的分散式鎖框架基於wiki呈現方式的文件目錄。前面的序號是為了方便與使用者基於文件的溝通(與使用者的直接溝通是難以避免的)。

(圖二)

3、細化落地

看完上面示例圖後,理解會稍微直觀點,接下來我將上面的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:可以在此頁面歸納整理較為典型的/常見的使用者疑問,方便其他有類似疑問的同事看(類似最佳實踐),減少溝通工作量。需要注意的是,此處只是臨時性的公共問題導引地址,從長遠看,使用者常問的問題需要從系統設計層面進行優化,或者要在詳細使用說明處進行顯著提示。

四、框架文件要怎麼寫

文件的閱讀者一般是程式設計師,程式設計師的思維邏輯性較強,因此我們寫出來的文件具備較強的邏輯性是基礎要求,以下從三個維度來描述文件的邏輯性。

1、功能框架邏輯

文件的整體邏輯建議依據上面的6個分類內容進行“總-分-總”式編寫。首先要對框架進行整體介紹,這個可以放到框架首頁,接著明確要輸出文件的類別(按照框架的不同可以選擇性的寫對應類別的文件,當然不是一定要輸出全部6個類別的文件)及對框架功能特性進行列舉,這是一個“總-分”的過程。接著可以將單個類別的文件或者單個特性的說明文件作為獨立的模組,進行詳細說明。另外,使用者檢視頻率較高的部分,也應該新增選單單獨編寫,方便使用者快讀查詢瀏覽。我們看下分散式鎖框架文件的主頁:

(圖三)

單個類別的文件在編寫的時候,也需要視具體內容的複雜度,多次進行“總-分”形式的拆分。多次拆分後一般需要再次“總”的過程,來組合成一個完整的功能特性。

在圖二分散式鎖框架的文件目錄中,從功能框架邏輯上來說,“依賴與限制”內容雖然也會比較少,但是一般在使用一個框架的時候是必看的內容,因此這裡將其作為獨立的模組。“快速開始”顧名思義就是引導使用者快速瞭解框架,非常重要,注意要以最簡潔的話語、最簡的配置、最少的程式碼、最少的依賴,以最小的篇幅來進行說明,目標是2分鐘內能看懂。“配置手冊”當然是羅列的全部的框架配置相關,包含功能、效能的調節引數,還要注意將常用配置與不常用的分開,總之一個原則,保持全面完整但是也要按使用頻次歸類。“詳細說明”主要從使用者接入、使用、調優、注意事項等角度,對框架進行全方位的說明,一般會佔有最大的篇幅。“多場景demo示例”建議列舉使用者所有的使用場景,針對場景提供示例程式碼。“版本與升級”其實就是釋出與變更日誌,版本相容性說明,相應的使用者的升級注意事項。

如下為我們團隊開發的分散式鎖框架”詳細說明“頁面的目錄:

(圖四)

2、功能流程邏輯

2.1 功能使用

功能流程邏輯可以理解為一個功能使用時的多個具體步驟的串聯。例如使用分散式鎖框架的典型步驟如下:

通過maven依賴分散式鎖框架jar包->配置zookeeper或者redis的地址->編碼(獲取鎖)->編碼(釋放鎖)

這個過程這麼寫大家會不會覺得就很明白也很不明白?雖然整體流程是很簡單,但是文件絕不可以只是寫這些內容,否則會給開發者帶來無盡的使用者溝通。例如文件還應當包含:指明某個功能最低版本(依賴什麼版本的包合適),spring環境、spring boot環境、純java環境如何依賴,依賴的三方包衝突範圍及排查方法,zookeeper配置引數以及叢集可用性與框架穩定性說明,zookeeper連線管理說明,鎖獲取與釋放過程可重入性說明,異常處理指導,最佳實踐等等,這還是API最基本的使用方式,換做是註解的使用方式,需要說明的細節就更多了。至於應該寫清楚哪些細節,可以是逐漸完善的,文件也是需要不斷迭代更新的。

為了使用者好閱讀,建議以流程圖的形式,分使用場景逐個進行說明。每個步驟要將相關的細節說清楚,避免使用者使用過程的電話溝通確認。

2.2 原理與原始碼解釋

在進行框架原理或者原始碼的描述時,時常涉及到狀態變化描述、生命週期描述等等,顯然使用常規流程圖不足以表達清晰,此時換做狀態轉化圖、時序圖、加上了泳道的流程圖,效果會更好。我們看下TCP連線生命週期狀態轉化圖:

(圖五)

3、功能描述邏輯

在功能流程邏輯中有寫到,流程中的每一個步驟,都要寫清楚相應的細節,通過文件的不斷更新迭代來完善。這裡如何把這些細節有條理、完整的描述清楚,需要注意以下幾點:

  • 完整:列舉所有的可能項,逐個說明,不要有疏漏;
  • 考慮所有影響點:例如一個功能配置的變動,可能影響到其他功能;再如如果分散式鎖框架中提到的fallback方法返回引數型別與正常業務方法返回引數型別不相容會怎樣?不要讓使用者去問你;
  • 條件判斷清晰:例如在滿足什麼條件會觸發什麼邏輯,可以使用if/else/while寫出虛擬碼;
  • 含義明確:所見即所得,用詞嚴謹達意,不可模稜兩可;
  • 敘述背景:如果某個功能不是最佳實現,或者與開源方案有差異,最好敘述背景,讓使用者理解你。

五、總結

最後,要意識到每個人的思維方式、邏輯習慣是有差異的,無論花多少心思去寫文件,都難以做到十全十美不遺漏無疏忽,因此還需要一個使用者反饋的渠道,例如大多數文件系統都有評論功能。下圖是文件聯絡起使用者與開發者後的成熟態。

(圖六)

文件編寫的基本目的,是幫助使用者來使用框架,但是不能忽略的是,框架的開發者也是文件的重要使用者,文件在方便使用者的同時,也要方便自己。

本文從日常諮詢存在的問題引發出思考,聯想到文件也是一個產品,用來解決特定人群的問題。因為不懂產品,不能從產品的專業角度對文件進行解構,只能根據自己經驗說明文件應該要寫哪些內容,從功能框架、特性使用流程、功能描述時注意事項等說明了文件編寫的邏輯性。希望對同樣從事開發框架的開發與維護的同行一點啟發。

作為框架的開發者,使用者的肯定與點贊是我們最好的回報。我們會注重編碼質量,但是往往忽略文件的重要性,框架很牛逼但是文件寫得很爛,使用者用起來不順暢,會讓框架的價值大打折扣。意識到這一點很重要,寫出牛逼的程式碼,文件也寫得清晰易讀,使用者才會覺得框架牛逼,順帶才會認為作者牛逼。牛逼的事情做多了,你的技術影響力自然就上來了。

更多內容敬請關注vivo 網際網路技術微信公眾號

注:轉載文章請先與微訊號:Labs2020聯絡。

相關文章