程式庫作者建立具備資訊性文件的最佳實務
為你的程式庫提供文件至關重要。 它決定了使用者是否會研究你的程式庫、是否會在專案中採用它,以及在遇到困難時是否能堅持下去。 現今的開發人員在語言、程式庫、架構和平台之間擁有前所未有的選擇。 因此,吸引並告知你的使用者是必不可少的;否則,他們可能會尋求其他選擇。
在程式庫的早期版本中,來自使用者的回饋將會非常稀少。 幸運的是,建立與完善文件可以作為一種回饋循環,大大提高專案的品質。 因此,建立文件不應被視為一種負擔,也不應在建立程式庫時被推遲到優先順序列表的後方。
有效的文件不僅能告知使用者,還能推動程式庫的開發與完善。 以下是文件引導開發過程的幾個關鍵方式:
- 你應該能夠用幾段話解釋你的程式庫的作用、誰會從中受益,以及與其他替代方法相比有哪些優勢。如果你做不到這一點,請重新考慮專案的範圍和目標。
- 你應該能夠建立一個「快速入門指南」,讓潛在使用者能盡快上手執行。所謂的盡快取決於問題領域,但你可以與其他平台上的類似程式庫進行比較。該指南應引導使用者進入一個回饋循環,使過程變得越來越簡單快速,同時始終產生可靠的結果。建立此指南將幫助你識別出可能阻礙使用者進度的複雜度突然增加(懸崖效應)。
- 記錄函式的行為會迫使你考慮所有的邊緣情況,例如輸入的有效範圍、可能拋出的例外,以及效能如何隨工作量增加而下降。這通常可以改進函式簽章和底層實作。
- 如果初始化程式庫所需的程式碼總是蓋過完成任務所需的程式碼,請重新思考你的配置選項。
- 如果你無法針對使用標準選項執行基本任務建立清晰的範例,請考慮針對日常使用最佳化你的 API。
- 如果你無法在不使用真實資料來源和線上服務的情況下演示如何測試你的程式庫,請考慮為存取網路(以及一般的外部世界)的元件提供測試替身。
越早為程式庫提供文件,就能越早讓真實世界的使用者進行測試。 來自這些測試的回饋隨後可用於改進設計。
提供全面的文件
你的程式庫必須提供足夠的文件,讓使用者以最小的努力採用它。 這些文件應包括:
- 快速入門指南
- API 的深度描述
- 常見使用案例的較長範例(也稱為食譜 recipes)
- 資源連結,例如部落格、文章、在線講座和會議演講
快速入門指南應涵蓋你的程式庫如何與支援的建置系統整合。 它應包含對最常用實體的簡要說明,並附上如何使用它們的小範例。 在程式庫與外部世界互動的每個點上,請指明配置環境的必要步驟, 以及如何驗證這些步驟已成功完成。 如果不需要任何步驟,請明確說明。
如果可能,請為你支援的每個程式庫版本提供單獨版本的文件。 這可以防止使用者查看到過時或過於超前的資訊。 當無法做到這一點時,請清晰地標記文件中與已重新設計的 API 部分相關的章節。
為你的使用者建立人物誌
在沒有清楚瞭解目標受眾的情況下建立和評估文件是具有挑戰性的。 為閱讀你文件的使用者類型定義多個人物誌 (personas) 會很有幫助。
考慮使用者的限制,例如他們需要運行的預先存在的軟體堆疊。 文件的審查者可以採用這些人物誌,使他們的結論更有意義。
當你缺乏關於使用者的具體資訊時,最好保持悲觀。 例如,不要假設使用者精通 Kotlin 的最新或最進階特性。 讓你的程式碼範例儘可能保持簡單。
當由於時間、預算限制或保密協議而無法諮詢真實使用者時,人物誌特別有用。 隨著時間的推移,當你對使用者有了更好的瞭解,請精確地改進人物誌以符合他們的需求。
盡可能透過範例記錄文件
透過範例記錄文件是向使用者解釋基本概念最符合成本效益的方法之一。 只要有可能,請提供簡單清晰的程式碼範例,幫助解釋或演示當前討論的主題或概念。
KDoc 文件格式允許你在文件註解中使用使用 Markdown 的內嵌標記。 在註解中使用內嵌程式碼片段來展示 API 的用法。 範例請參閱 coroutine 程式庫中測試調度器的原始碼與渲染後的文件。
提供這樣的範例可以避免編寫冗長的預期輸入、可能輸出和失敗模式的描述。 然而,每個範例的上下文必須清晰,其相關的情況也必須明確。 僅僅提供一個包含未加註解的範例程式資料夾並不算是文件。
徹底記錄你的 API
每個受支援的 API 入口點都應使用 KDoc 進行記錄。
Kotlin 的文件引擎 Dokka 預設在其輸出中僅包含公開宣告。如簡潔性章節所述, 你應該最小化你的公開 API,並移除你不希望使用者存取的公開入口點。 如果有些 API 你無法透過控制可見性來隱藏,請使用 suppress 指示詞將它們從文件中省略。
在描述入口點時,請先對函式的作用進行清晰、高階的描述。 避免僅僅用自然語言轉述簽章內容。
例如,不要說「接受一個 String 並傳回一個 Connection」,而應改說 「嘗試連接到輸入字串指定的資料庫,如果成功則傳回 Connection,否則拋出 ConnectionTimeoutException」。
指定每個輸入的預期值以及不同輸入下的行為。 解釋有效值的範圍,以及提供無效值時會發生什麼事。 例如,如果字串輸入應該是一個 URL,請描述當字串為空、無效、使用不支援的協定或指向不存在的位置時會發生什麼事。
記錄 API 入口點可能拋出的每個例外。在一般描述中討論失敗條件,並將例外章節保留給詳細資訊。這可以增強可讀性並幫助讀者集中注意力。相反地,將這些資訊有機地整合到一般描述中。盡可能提供用法範例也有助於使用者理解如何正確使用 API。
我們建議學習技術寫作,以提高文件的清晰度和有效性。 考慮探索資源,例如 Google 的這門課程(第一部分和第二部分)。
記錄 Lambda 參數
當 API 入口點接受 Lambda 時,使用者提供的是你的程式庫將代表他們執行的某些功能。 這至少需要在兩個方面提供額外文件。
首先,記錄如果 Lambda 拋出例外會發生什麼事。請考慮解決以下問題:
- 這會導致立即失敗、Lambda 會被重複呼叫,還是有備援行為?
- 如果呼叫函式需要結束,它會重新拋出從 Lambda 拋出的例外,還是拋出一個不同的例外?
- 如果例外不同,它會包含原始例外嗎?
此外,除非函式被宣告為 inline,否則請記錄與並行相關的任何特殊行為。 確保涵蓋以下內容:
- Lambda 是否會在與呼叫者相同的執行緒中被呼叫?
- 如果 Lambda 不在與呼叫者相同的執行緒中被呼叫,它將在哪個執行緒(或執行緒池)中被呼叫?
- 是否會並行執行 Lambda 的多個副本?
- 還有哪些其他工作可能正在使用該執行緒?
- 使用者是否可以指定程式庫使用的執行緒?
- 在呼叫多個 Lambda 的情況下,關於順序提供了哪些保證?
在文件中使用明確連結
API 入口點完全獨立於程式庫中的其他功能是非常罕見的。 通常,呼叫必須按特定順序進行,執行特定任務有多種選項, 且執行相關任務的入口點會以類似的方式使用。 例如,像 format 和 parse 這樣的函式互為映照。
使用 @see 標籤或內部連結在你的文件中使這些關係變得明確。 這可以讓讀者將資訊塊組化 (chunk),從而建立一個整合更好的程式庫心理地圖,對讀者有所幫助。
盡可能保持自給自足
在描述什麼是有效輸入時,很容易僅僅引用相關標準,例如由 W3C、IEEE 或 Unicode 聯盟制定的標準。 雖然提供這些連結可能有所幫助,但不應強迫讀者查閱外部規範來發現基本資訊, 例如空白字元集。
只要有可能,文件就應該是自給自足的。 它應該為使用者提供足夠的資訊,以便理解每個 API 入口點的典型用法。 對於在常見使用中不會發生的邊緣情況,你可以引導使用者參考外部文件。
使用簡單的英語
在建立文件時使用簡單清晰的英語非常重要。 這確保了你的內容對於全球讀者來說是易於理解的,包括那些母語不是英語的人。 避免使用複雜的單字、術語、拉丁語短語或可能使讀者困惑的慣用語。 相反,請使用直接的語言和簡潔的句子。
簡單的英語也使文件在需要時更容易翻譯。 清晰、明確的文字降低了誤解的風險,並提高了整體的閱讀體驗。
下一步
如果你還沒有看過,請考慮查看這些頁面:
