📝

『エンジニアチームの生産性の高め方』第2章 Design Doc 要点まとめ

に公開

『エンジニアチームの生産性の高め方』(ISBN-10:4297145022) 第2章でDesign Docについて読んだ。

Design Doc的なものは様々な案件で書いてきたが、
何のために/何を書くべきか明確化するため、
自分にとって役立ちそうな内容を以下まとめた。
特に重要な箇所は太字にした。

2-1 Design Doc とは

Design Docとは、新機能開発やリファクタリングのようなタスクに対し「どう実装するか(How)」「実装したいことを実現するための設計」を書くドキュメント。以下のような多岐な用途で使われるが、この本の記述からは主に設計について議論するために書くと読み取れる。

  • 下調べの備忘録
  • 開発者の考えを整理
  • 議論のための資料や議事録
  • 工数見積の参考資料
  • 意図を後から知る手がかり

新機能開発や大規模リファクタリングでは書いた方が良いが、以下もDesign Docを書いたほうが良い具体例。

  • サードパーティに公開するAPIの追加
  • 複数のテーブルにまたがるDBスキーマの更新
  • アプリケーション全体で使われる新ライブラリの導入

書くタイミング

「PRD(Product Requiements Document)などによる要件定義」 ⇄ 「Design Docによる設計」 ⇄ 「実装」

上記のように、各フェーズ間には検証・修正のフィードバックサイクルが生じる。
各フェーズの成果物は一度書いたら終わりではなく、随時修正する。

何を使って書くか

  • 共同編集できる(できればリアルタイム)
  • 履歴管理できる
  • コメントやレビューを残せる
  • 集積・検索できる

ツール例:

  • Google Docs
  • Notion
  • Dropbox Paper
  • Confluence
  • Github上でmdファイルとして管理する

2-2 Design Doc の構成

基本方針

トップダウンな説明を心がける。

  • 全体から部分へ
  • 抽象から具体へ
  • 事実から理由へ
  • 原則から例外へ

トップダウンなDesign Docのセクション例

  • タイトル
  • 目的: 何を実装するか
  • 背景: なぜ実装するか、前提知識
  • 設計概要: どう実装するかの概要
  • 設計詳細: どう実装するかの詳細・具体的説明
  • 計画: 実装やリリースの順番についての説明
  • その他: セキュリティ、プライバシー、パフォーマンスなど

以下、各セクションについて説明

タイトル

多少長くなったとしても、説明的な方が好ましい。
特殊な用語や特定のモジュールでしか使わない用語などは使わないこと。

目的セクション

数段落程度で説明する。
何を実装しないか(スコープ外)も書く。

背景セクション

必要性や理由については、要件定義やPRDなどのドキュメントへのリンクで済ませるのがよい。
このセクションでは以下のような前提知識を書く。

  • コンポーネント固有の用語
  • コードがどこにあるか
  • 現状の設計、仕様や課題

また、以下のような設計に影響する要素を書く。

  • 満たすべき内部品質(例: パフォーマンス、スケーラビリティ、変更容易性、など)
  • 実装時の制約(例: 利用可能なライブラリ、サポートするプラットフォームバージョンなど)

設計概要セクション

全体像、基本的なアイデアや、簡略なシーケンス図やデータフロー図を書く。

全体像

重要なモジュール、データモデル、クラス、APIとその役割を書く。
この本には、主要なクラスについてテキストとクラス図で説明する例が示されている。
図を使う場合、以下に気をつける。

  • 要素の説明をする
  • 作図に時間をかけすぎない
    • 紙に描いた図を写真に取るで十分なことも多い
    • drawioやLucidchart
    • テキストベースなら、MermaidやPlantUML
  • 詳細に書き過ぎない
    • 例: クラスのメンバや関連の薄いクラスなどを書かない
  • 何が変わるのかを明確にする
    • 例: 塗りつぶしや線の種類で新規・既存を示す
    • 例: 現在の状況と提案とで図表を分ける

基本的なアイデア

特に気をつけるべき点をどう達成するのかを説明する。
例えば、単位時間あたりのクエリ数の想定によって、
データ永続化の方法やキャッシュ戦略、スケール化などの設計は異なる。
他にもオペレーション失敗時のエラーハンドリングの解決策をどうするかなど。

設計詳細セクション

クラスやモジュール別、
挙動のパターン別、
ステップ別、
などの基準でサブセクションを切って処理詳細説明を書く。
また、代替案の比較結果があれば書く。

(私見)処理詳細説明は、処理が複雑で手戻りが大きくなりそうな可能性がある場合に書く、くらいが妥当かも。さほど複雑でない処理なら、くどくどと処理詳細説明をするよりも、実際のコードを書いた方が早いことも多い。
また、実際に実装してみて初めて見えてくることも多い。事前に書くのが難しかったり、書いても的外れになることも多い。

代替案の比較

アーキテクチャやデザインパターン、FWやライブラリに代替案があるなら、設計詳細セクションで比較結果を示すと良い。

計画セクション

以下のような場合に実装の順番やマイルストーンを説明する。

  • モジュールやクラスに依存関係がある場合
  • 事前にリファクタリングが必要な場合

また、段階的なリリースが必要ならその計画を説明する。

2-3 Design Doc 運用上の注意点

短いフィードバックサイクルを心がける

  • 最初から完成されたドキュメントを書こうとしない
  • 議論と内容の更新を細かく繰り返し、短いフィードバックサイクルを作る
  • 実装中によりよい設計が思い浮かんだらDesign Docに戻って更新するのを厭わない
    • 同様に、「目的自体が間違っていないか」と感じた場合はDesign Docを中断し、PRDの議論に戻る

Design Docはタスクごとに使い捨てる

Design Doc以外の選択肢を持つ

コードレビューで設計の議論をすることもできる。Design Docを書くほどではないが、複数コードレビュー(≒PR)に分ける必要がある程度には大きいタスクに有効である。以下に詳述。

コードレビューで設計の議論をする方法

最初のPRには詳細実装を含めず、構造と依存関係だけのスケルトンコードを書く。
この段階でレビューを依頼し、設計の議論をする。
設計の合意が取れたら、詳細実装時のPRに最初のPRへのリンクを貼

Discussion