ライブラリ作者が有益なドキュメントを作成するためのベストプラクティス
ライブラリに対して提供するドキュメントは極めて重要です。 ドキュメントの内容次第で、ユーザーがそのライブラリを検討するか、プロジェクトに採用するか、そして困難に直面したときに使い続けてくれるかが決まります。 今日の開発者は、言語、ライブラリ、フレームワーク、プラットフォームにおいて、かつてないほど多くの選択肢を持っています。 そのため、ユーザーを惹きつけ、必要な情報を提供することが不可欠です。さもなければ、彼らは他の選択肢へと移ってしまうでしょう。
ライブラリの初期バージョンでは、ユーザーからのフィードバックは乏しいものです。 幸いなことに、ドキュメントを作成し洗練させていくプロセスは、プロジェクトの品質を大幅に向上させるフィードバックループとして機能します。 そのため、ドキュメント作成を負担と考えるべきではなく、ライブラリ作成時の優先順位を下げるべきでもありません。
効果的なドキュメントは、ユーザーに情報を提供するだけでなく、ライブラリの開発と洗練を促進します。ドキュメントが開発プロセスを導く主な方法は以下の通りです。
- ライブラリが何をするのか、誰がそれを使用することで恩恵を受けるのか、代替アプローチと比較してどのような利点があるのかを、数段落で説明できるようにすべきです。これができない場合は、プロジェクトのスコープや目的を再検討してください。
- 潜在的なユーザーができるだけ早く使い始められるような「スタートガイド(Getting Started guide)」を作成できるようにすべきです。「早く」がどの程度の時間を指すかは問題領域によりますが、他のプラットフォームにある同様のライブラリと比較検討できます。このガイドは、常に信頼できる結果を出しつつ、作業がより簡単かつ迅速になっていくフィードバックループにユーザーを導くものであるべきです。このガイドを作成することで、ユーザーの進捗を妨げるような、複雑さの急激な増加(クリフエッジ)を特定するのに役立ちます。
- 関数のドキュメントを作成する作業により、入力の有効な範囲、スローされる可能性のある例外、負荷が増大したときのパフォーマンスの低下など、あらゆるエッジケースを考慮せざるを得なくなります。これは多くの場合、関数のシグネチャや基盤となる実装の改善につながります。
- ライブラリの初期化に必要なコードが、タスクを達成するために必要なコードを常に上回っている場合は、構成オプションを再考してください。
- 標準的なオプションを使用した基本的なタスクの実行について、明確な例を作成できない場合は、日常的な使用に合わせて API を最適化することを検討してください。
- 実際のデータソースやオンラインサービスを使用せずにライブラリをテストする方法を示せない場合は、ネットワーク(および一般的な外部環境)にアクセスするコンポーネントに対して、テストダブル(test doubles)を提供することを検討してください。
ライブラリのドキュメントを早く提供すればするほど、実世界のユーザーによるテストを早く受けることができます。 これらのテストからのフィードバックは、設計の改善に役立てることができます。
網羅的なドキュメントを提供する
ライブラリは、ユーザーが最小限の労力で導入できる十分なドキュメントを提供しなければなりません。 このドキュメントには以下を含める必要があります。
- スタートガイド(Getting Started guide)
- API の詳細な説明
- 一般的なユースケースに対する長めの例(レシピとも呼ばれます)
- ブログ、記事、ウェビナー、カンファレンストークなどのリソースへのリンク
スタートガイドでは、サポートされているビルドシステムとライブラリをどのように統合するかを説明する必要があります。 また、最も一般的に使用されるエンティティの簡潔な説明と、それらがどのように使用されるかの小さな例を含めるべきです。 ライブラリが外部環境と相互作用する各ポイントにおいて、環境を構成するために必要な手順と、それらの手順が正常に完了したことを確認する方法を明記してください。 手順が不要な場合は、その旨を明示してください。
可能であれば、サポートするライブラリのバージョンごとに個別のドキュメントを提供してください。 これにより、ユーザーが古すぎたり、新しすぎたりする情報を閲覧してしまうのを防ぐことができます。 これが不可能な場合は、再設計された API の一部に関連するドキュメントのセクションを明確にマークしてください。
ユーザーのペルソナを作成する
想定される読者を明確に理解せずにドキュメントを作成・評価するのは困難です。 ドキュメントを読むユーザーのタイプに合わせて、複数のペルソナを定義すると役立ちます。
ユーザーが操作する必要のある既存のソフトウェアスタックなど、ユーザーの制約事項を考慮してください。 ドキュメントの査読者は、これらのペルソナを採用することで、その結論をより意味のあるものにできます。
ユーザーに関する具体的な情報が不足している場合は、悲観的に考えるのが最善です。 例えば、ユーザーが Kotlin の最新機能や高度な機能に精通していると仮定しないでください。 コード例はできるだけシンプルに保ってください。
ペルソナは、時間や予算の制約、または機密保持契約のために実世界のユーザーに相談できない場合に特に役立ちます。 時間の経過とともにユーザーへの理解が深まったら、彼らのニーズにより正確に一致するようにペルソナを洗練させてください。
可能な限り例を用いて説明する
例を用いたドキュメント作成は、ユーザーに基本概念を説明するための最も費用対効果の高い方法の一つです。 可能な限り、現在議論されているトピックや概念を説明・実演するのに役立つ、シンプルで明確なコード例を提供してください。
KDoc ドキュメント形式では、ドキュメントコメント内で Markdown を使用したインラインマークアップ を使用できます。 コメント内のインラインコードスニペットを使用して、API の使用方法を示してください。 例として、コルーチンライブラリのテストディスパッチャの ソースコード と レンダリングされたドキュメント を参照してください。
このような例を提供することで、期待される入力、考えられる出力、および失敗モードに関する長い説明を書く必要がなくなります。 ただし、各例のコンテキストと、それが関連する状況を明確にする必要があります。 単にコメントのないサンプルプログラムのフォルダを提供するだけでは、ドキュメントとは言えません。
API を徹底的にドキュメント化する
サポートされているすべての API エントリポイントは、KDoc を使用してドキュメント化されるべきです。
Kotlin のドキュメントエンジンである Dokka は、デフォルトで公開宣言(public declarations)のみを出力に含めます。シンプルさ のセクションで説明したように、 公開 API を最小限に抑え、ユーザーにアクセスさせたくない公開エントリポイントを削除する必要があります。 可視性を制御することでユーザーから隠すことができない API がある場合は、suppress ディレクティブ を使用してドキュメントから除外してください。
エントリポイントの説明は、その関数が何を行うかについての明確でハイレベルな記述から始めてください。 シグネチャを自然言語で単に言い換えることは避けてください。
例えば、「String を受け取り Connection を返す」と言うのではなく、 「入力文字列で指定されたデータベースへの接続を試み、成功した場合は Connection を返し、そうでない場合は ConnectionTimeoutException をスローする」といった具合です。
各入力の期待値と、異なる入力に対する動作を指定してください。 有効な値の範囲と、無効な値が提供されたときに何が起こるかを説明してください。 例えば、文字列入力が URL であることが想定されている場合、文字列が空、無効、サポートされていないプロトコルを使用している、 または存在しない場所を参照している場合に何が起こるかを記述してください。
API エントリポイントがスローする可能性のあるすべての例外をドキュメント化してください。失敗条件については一般的な説明の中で触れ、例外セクションは詳細な情報のために予約してください。これにより読みやすさが向上し、読者が集中しやすくなります。代わりに、この情報を一般的な説明の中に有機的に組み込んでください。可能な限り使用例を提供することも、ユーザーが API を正しく使用する方法を理解するのに役立ちます。
ドキュメントの明快さと効果を高めるために、テクニカルライティングについて学ぶことをお勧めします。 Google が提供しているコース(パート 1 および パート 2)などのリソースを検討してみてください。
ラムダパラメータをドキュメント化する
API エントリポイントがラムダを受け取る場合、ユーザーはライブラリが代わりに実行する何らかの機能を提供していることになります。 これには、少なくとも 2 つの領域で追加のドキュメントが必要です。
第一に、ラムダが例外をスローした場合に何が起こるかをドキュメント化してください。以下の質問に対処することを検討してください。
- これは即時の失敗を引き起こすのか、ラムダが繰り返し呼び出されるのか、それともフォールバック動作があるのか。
- 呼び出し元の関数が終了する必要がある場合、ラムダからスローされた例外を再スローするのか、それとも別の例外をスローするのか。
- 例外が異なる場合、元の例外は含まれるのか。
さらに、関数が inline として宣言されていない限り、並行性(concurrency)に関する特別な動作をドキュメント化してください。 以下の内容がカバーされていることを確認してください。
- ラムダは呼び出し元と同じスレッドで呼び出されるか。
- ラムダが呼び出し元と同じスレッドで呼び出されない場合、どのスレッド(またはスレッドプール)で呼び出されるか。
- ラムダの複数のコピーが並列に実行される可能性があるか。
- 他のどのジョブがそのスレッドを使用している可能性があるか。
- ユーザーはライブラリが使用するスレッドを指定できるか。
- 複数のラムダが呼び出される場合、実行順序に関してどのような保証があるか。
ドキュメント内で明示的なリンクを使用する
API エントリポイントがライブラリ内の他の機能と完全に独立していることは非常に稀です。 通常、呼び出しは特定の順序で行われる必要があったり、特定のタスクを実行するための複数のオプションがあったり、 関連するタスクを実行するエントリポイントが同様の方法で使用されたりします。 例えば、format と parse のような関数は互いに鏡のような関係にあります。
@see タグや 内部リンク を使用して、ドキュメント内でこれらの関係を明示してください。 これにより、読者は情報を チャンク化(構造化) することができ、ライブラリのより統合されたメンタルマップを構築するのに役立ちます。
可能な限り自己完結させる
入力が有効である理由を説明する際、W3C、IEEE、Unicode Consortium などが作成した関連標準を単に参照したくなることがあります。 これらのリンクを提供することは役立ちますが、読者は空白文字のセットのような基本的な情報を知るために 外部仕様を参照することを強いられるべきではありません。
可能な限り、ドキュメントは自己完結しているべきです。 各 API エントリポイントの典型的な使用法をユーザーが理解するのに十分な情報を提供すべきです。 一般的な使用では発生しないエッジケースについては、ユーザーを外部ドキュメントに誘導しても構いません。
簡潔な英語を使用する
ドキュメントを作成する際には、簡潔で明快な英語を使用することが重要です。 これにより、英語を第一言語としない人々を含む世界中の読者がコンテンツにアクセスできるようになります。 読者を混乱させる可能性のある複雑な単語、専門用語、ラテン語のフレーズ、または慣用句の使用は避けてください。 代わりに、平易な言葉と簡潔な文章を使用してください。
簡潔な英語は、必要に応じてドキュメントを翻訳しやすくもします。 明快で曖昧さのないテキストは誤解のリスクを減らし、全体的な読みやすさを向上させます。
次のステップ
まだ確認していない場合は、以下のページもチェックしてみてください。
- メンタルモデルの複雑さの最小化 ページで、精神的な複雑さを最小限に抑えるための戦略を探索してください。
- 後方互換性 ページで、後方互換性の維持について学んでください。
