BppLOG

Berlin → Tokyo

【翻訳】Googleのエンジニアがソフトウェア開発する時に必ず書くドキュメント「Design Docs at Google」

Googleでの「Design Docs」とは 2007年の Google Developer Day Tokyo での鵜飼氏のプレゼンによると「Google で必ず書くことになっているドキュメント」であり、「プロジェクト立ち上げ時の 1~2週間をかけて書く」ものです。
今回は Google のソフトウェアエンジニアである @cramforce 氏が自身のブログで「Googleでの Design Docs」について解説している記事を公開されていたため、氏の許可を得て翻訳しています。

原文:
www.industrialempathy.com


読了目安:11分

(目次)


Google のソフトウェアエンジニアリング文化の重要な要素の 1 つは、デザインドキュメントを通じてソフトウェア設計を定義することです。これは、ソフトウェアシステムやアプリケーションの作成者が、コーディングに着手する前に作成する比較的形式ばらないドキュメントです。設計書には、実装のアプローチと主要な設計上の決定事項が記載されており、その際に考慮されたトレードオフにも重点を置いて文書化されています。

ソフトウェアエンジニアとしての私たちの仕事は、コードを作成すること自体ではなく、むしろ問題を解決することです。設計書のような構造化されていないテキストは、より簡潔で理解しやすく、コードよりも高いレベルで問題と解決策を伝えることができるため、プロジェクトのライフサイクルの初期段階で問題を解決するのに適したツールとなるかもしれません。

ソフトウェア設計のオリジナルドキュメントに加えて、設計ドキュメントはソフトウェア開発ライフサイクルにおいて次の機能を果たします:

  • 変更を行う際に、設計上の問題点を早期に特定することは、手戻りが少なくて済む。
  • 組織内での設計の合意形成を達成する。
  • 横断的な懸念事項を確実に考慮する。
  • 上級エンジニアの知識を組織に浸透させる。
  • 設計の意思決定に関する組織の記憶の基礎を形作る。
  • ソフトウェア設計者の技術的なポートフォリオの中で、要約の成果物としての役割を果たす。

デザインドキュメント の解剖学

デザインドキュメントは形式ばらないドキュメントであるため、内容に関する厳格なガイドラインには従いません。
ルールその1: 特定のプロジェクトにとって最も意味のある形で書くこと。

とはいえ、ある構造は本当に便利なものとして確立されています。

文脈と範囲

この章では、新しいシステムが構築されようとしている風景と、実際に何が構築されようとしているのかについて、非常にざっくりとした概要を読者に提供します。これは要件書ではありません。簡潔にしてください。目標は、読者をスピードアップさせることですが、ある程度の予備知識を想定し、詳細な情報をリンクさせることができます。この章は、客観的な背景や事実に完全に焦点を当てるべきです。

目標と非目標

システムの目標が何か、時にはより重要なのは、何が非目標なのか、箇条書きにした短いリスト。 非目標は「システムがクラッシュしてはならない」などの否定された目標ではなく、合理的に目標である可能性があるものの、明示的に目標ではないことが選択されていることに注意してください。 良い例は「ACID」(*1)です。 データベースを設計するときは、それが目標か非目標かを確実に知りたいでしょう。 そして、それが非目標であっても、目標の達成を妨げるトレードオフが発生しなければ、それを提供する解決策を選択することかもしれません。

実際のデザイン

このセクションでは、まず概要を説明した後、詳細を説明します。

図:フクロウの描き方

デザインドキュメントは、ソフトウェア設計でのトレードオフを書き留める場所です。長期的な価値を持つ有用なドキュメントを作成するために、これらのトレードオフに焦点を当ててください。つまり、文脈(事実)、目標と非目標(要件)があれば、デザインドキュメントは解決策を提案し、特定の解決策がなぜそれらの目標を最もよく満たすのかを示す場所です。

形式ばらないドキュメントを書くことのポイントは、問題設定を適切な方法で表現するための柔軟性を提供することです。このため、設計を実際にどのように記述するかについての明確な指針はありません。

そうは言っても、いくつかのベストプラクティスや繰り返しのトピックが出てきており、デザインドキュメントの大部分にとって意味のあるものとなっています。

システムコンテキスト図

多くのドキュメントでは、システムコンテキスト図が非常に役立ちます。このような図は、システムをより大きな技術的展望の一部として示し、読者がすでに慣れ親しんでいる環境を考慮して新しい設計をコンテキスト化することを可能にします。

システムコンテキスト図の例
システムコンテキスト図の例

API

設計中のシステムが API を公開している場合は、その API を記載するのが一般的です。しかし、ほとんどの場合、正式なインターフェースやデータの定義は冗長で不要な詳細が含まれており、すぐに古くなるため、コピー&ペーストをしたくなる誘惑には耐える必要があります。その代わりに、設計とのトレードオフに関連する部分に焦点を当ててください。

データストレージ

データを保存するシステムでは、いつ、どのような形で発生するのかを議論すべきでしょう。APIに関するアドバイスと同じ理由で、完全なスキーマ定義をコピー&ペーストすることは避けるべきです。設計とのトレードオフに関連する部分に焦点を当ててください。

コードと疑似コード

設計書には、新しいアルゴリズムが記述されている場合を除いて、コードや擬似コードを含むことはほとんどありません。必要に応じて、設計の実現可能性を示すプロトタイプにリンクしてください。

制約の度合い

ソフトウェア設計の形、つまり設計書に影響を与える主な要因の一つは、解決策の制約の度合いです。

極端な例としては、「グリーンフィールド・ソフトウェア・プロジェクト」(*2) がありますが、ここでは目標がわかっているだけで、解決策は何でもよいのです。このようなドキュメントは広範囲に及ぶかもしれませんが、管理可能な解決策にズームインすることを可能にする一連のルールを迅速に定義する必要があります。

もう一方では、可能な解決策が非常に明確に定義されているが、目標を達成するためにそれらをどのように組み合わせることができるのかが全く明らかではないシステムがあります。これは、変更が難しく、やりたいことができるように設計されていないレガシーシステムやライブラリ設計かもしれません。

このような状況では、比較的簡単に実行すべきことを列挙することができるかもしれませんが、目標を達成するためにはそれらを創造的に組み合わせる必要があります。複数の解決策があるかもしれませんし、どれも本当に素晴らしいものではないので、このようなドキュメントでは、特定されたすべてのトレードオフを考慮して最善の方法を選択することに焦点を当てなければなりません。

考慮された代替案

このセクションでは、同様の結果を合理的に達成したであろう代替設計を列挙する。それぞれの設計がもたらすトレードオフと、それらのトレードオフがどのようにして本ドキュメントの主要トピックである設計を選択する決定に至ったのかに焦点を当てるべきです。

結局選択されなかった解決策について簡潔に述べても構いませんが、このセクションは最も重要なセクションの一つです。なぜ選択された解決策がプロジェクトの目標から見て最適なのか、読者が疑問に思うような、他のソリューションが目標から見て望ましくないトレードオフをどのように取り入れているのかを非常に明確に示します。

横断的な懸念事項

ここでは、セキュリティ、プライバシー、観察可能性などの領域横断的な懸念事項が常に考慮されていることを確認することができます。これらの多くは、設計がどのように懸念事項に影響を与えるか、また、懸念事項にどのように対処するかを説明する比較的短いセクションです。チームは、自分たちのケースでこれらの懸念事項が何であるかを標準化する必要があります。

その重要性から、Googleのプロジェクトではプライバシー設計専用のドキュメントが必要とされており、プライバシーとセキュリティのための専用のレビューがあります。レビューはプロジェクトの立ち上げ時までに完了することが求められていますが、プライバシーとセキュリティのチームとできるだけ早くから関与して、設計がそれらを最初から考慮したものになるようにすることを推奨します。これらのトピック専用のドキュメントがある場合は、もちろん、中央のデザインドキュメントでは詳細には触れずに、それらを参照することができます。

デザインドキュメントの長さ

デザインドキュメントは、十分に詳細でなければなりませんが、忙しい人が実際に読めるくらいの短さが必要です。大きなプロジェクトでは約10〜20ページです。それ以上になると、問題をより管理しやすい単位に分割する方が理にかなっています。また、1〜3ページの「ミニデザインドキュメント」を書くことも可能です。これは、アジャイルプロジェクトでの段階的な改善やサブタスクに特に役立ちます。長いドキュメントの場合と同じ手順をすべて実行し、物事を簡潔にし、限られた問題に焦点を当てます。

デザインドキュメントを書いてはいけない時

デザインドキュメントの作成はオーバーヘッドです。デザインドキュメントを書くかどうかの判断は、設計、文書化、上級職によるレビューなどに関する組織的な合意形成のメリットが、デザインドキュメントの作成に伴う労力を上回るかどうかというトレードオフに帰着します。この決定の中心にあるのは、設計問題の解決策が曖昧であるかどうか、つまり問題の複雑さが原因なのか、解決策の複雑さが原因なのか、あるいはその両方なのかということです。そうでない場合は、ドキュメントを作成するプロセスを経る価値はほとんどありません。

デザインドキュメントが不要かもしれないという判断ポイントとしては、デザインドキュメントが実際には実装マニュアルになっていないかどうかです。トレードオフや代替案、意思決定の説明を行わずに、ドキュメントが基本的に「これが実装方法です」というだけの文書であれば (あるいは、解決策にトレードオフがなかったことを意味するほど明白であれば)、プログラムをすぐに書く方がいいでしょう。

最後に、デザインドキュメントの作成とレビューのオーバーヘッドは、プロトタイピングや迅速な反復作業とは相容れないかもしれません。しかし、ほとんどのソフトウェアプロジェクトは、実際に既知の一連の問題があります。アジャイル手法の講座に参加しているからといって、実際に知られている問題を解決するために時間をかけないという言い訳にはなりません。さらに、プロトタイピング自体は、デザインドキュメント作成の一部である可能性があります。「試してみたらうまくいった 」というのは、デザインを選択するための最良の議論の一つです。

デザインドキュメント のライフサイクル

デザインドキュメントのライフサイクルにおけるステップは以下の通りです。

  1. 作成と迅速な反復
  2. レビュー(複数回行う場合があります)
  3. 実装と反復
  4. メンテナンスと学習

作成と迅速な反復

ドキュメントを書くのはあなたです。時には、複数人で一緒に書くこともあるでしょう。

このフェーズでは、問題となっている領域について最も知識が豊富な同僚(多くの場合、同じチームに所属している)にドキュメントを共有し、彼らの明確な質問や提案を通じて、ドキュメントを安定したバージョンにまで仕上げていく、迅速なイテレーションが行われます。

ドキュメント作成にバージョン管理やコードレビューツールを好むエンジニアやチームもいるでしょうが、Google のデザインドキュメントの大部分は Google Docs で作成され、そのコラボレーション機能を大いに活用しています。

レビュー

レビューフェーズでは、デザインドキュメントは、元の筆者や共同編集者よりも幅広い読者と共有されます。レビューは多くの価値を与えることができますが、オーバーヘッドの危険な罠でもあるので、賢く扱いましょう。

レビューは様々な形をとることができます。より簡易な方法としては、(より広い)チームメンバーにドキュメントを送信して、みんなに見てもらう機会を与えるだけです。議論は主にドキュメント内のコメントスレッドで行われます。レビューの重要な側面としては、正式な設計レビュー会議であり、この会議では、著者が上級エンジニアの参加者に向けて(多くの場合、専用のプレゼンテーションを通じて)ドキュメントを説明します。Google の多くのチームでは、この目的のために定期的にミーティングが予定されており、エンジニアはレビューのために担当者を指名することができます。当然のことながら、このような会議が開催されるのを待っていると、開発プロセスが大幅に遅れることになります。エンジニアは、最も重要なフィードバックを直接求め、より広範なレビューの進捗を妨げないようにすることで、これを軽減することができます。

Google が小規模な会社だった頃は、デザインドキュメントを1つの中央のメーリングリストに送信し、上級エンジニアが自由にレビューするのが通例でした。これは、あなたの会社にとっては非常に良い方法かもしれません。1つの利点は、会社全体で比較的統一されたソフトウェア設計文化を確立できたことです。しかし、会社がはるかに大規模なエンジニアリングチームに規模を拡大するにつれ、中央集権的なアプローチを維持することは不可能になりました。

このようなレビューがもたらす主な価値は、組織の経験を統合して設計に反映させる機会を形成することです。最も一貫しているのは、観測性、セキュリティ、プライバシーなどの横断的な懸念事項を考慮に入れた設計を確保することは、レビューの段階で確保させていることである。レビューの主な価値は、それ自体が問題を発見することではなく、開発のライフサイクルの比較的早い段階で、変更を加えることの影響を小さく出来ることです。

実装と反復

プロジェクトが十分に進行し、さらなるレビューで設計の大幅な変更が必要になる可能性が低いという確信が持てるようになったら、コーディングを開始する時です。計画が現実と衝突するとき、つまり、欠点や未解決の課題が浮き彫りになった時、あるいは設計が間違っていると判明した時、設計の変更が必要になることは避けられません。このような場合には、設計ドキュメントを更新することを強くお勧めします。経験則として、設計したシステムがまだリリースされていない場合は、必ず設計書を更新してください。実際には、私たち人間はドキュメントを更新するのが苦手で、他の現実的な理由で変更が新しいドキュメントに分離してしまうことがよくあります。これは、最終的には、一貫した文書というよりは、多数の修正を伴う米国憲法のような状態になってしまいます。オリジナルのドキュメントからそのような分岐したドキュメントへのリンクは、将来の保守プログラマーがデザインドキュメントの考古学を通して対象のシステムを理解しようとしている場合にはきっと役立つでしょう。

メンテナンスと学習

Google のエンジニアがこれまで触ったことのないシステムに対面したとき、最初の質問は「設計書はどこにありますか?」ということがよくあります。設計書は、すべてのドキュメントと同様に、時間の経過とともに実際のシステムとは乖離していく傾向がありますが、それでも、システムの作成を導いた考え方を知るための最もアクセスしやすい入口を提示しています。

執筆者として、1年か2年後に自分の設計書を読み直してみてください。何が正しかったのでしょうか?何が間違っていましたか?今日ならあなたはどのような判断をしますか?これらの質問に答えることは、エンジニアとして成長し、時間をかけてソフトウェアの設計スキルを向上させる素晴らしい方法です。

結論

デザインドキュメントは、ソフトウェアプロジェクトで最も困難な問題を解決するために、合意を得るための優れた方法です。プロジェクトの目標を達成できず、事前の調査で回避できたかもしれないコーディングのラビットホールに陥る(* 本来の目的から逸れてしまうこと)ことを避けることができるので、コストを節約できます。だから、プロジェクトのために賢い選択をしてください。

設計書の作成を検討する際には、以下の点を考慮してください。

  • 適切なソフトウェア設計に確信が持てず、確実性を得るために事前調査に時間をかけることに意味があると言えますか?
  • 関連して、すべてのコード変更をレビューすることができない可能性のある上級アエンジニアを設計に参加させるのに役立ちそうでしょうか?
  • ソフトウェア設計が曖昧であったり、あるいは議論の余地があったりして、組織的な合意を得ることがプロジェクトでは重要になりそうでしょうか?
  • 私のチームは、プライバシー、セキュリティ、ロギング、その他の横断的な懸念事項を設計の中で考慮することを忘れてしまうことがありますか?
  • 組織内のレガシーシステムの設計について高レベルな洞察を提供するドキュメントの必要性が強く求められていますか?

これらの質問のうち3つ以上に「はい」と答えた場合、次のソフトウェアプロジェクトを開始するためには、おそらくデザインドキュメントは優れた方法です。

関連記事

Design docs – A design docDesign docs - A design doc


ここまで来たので、この記事をお気に入りのSNSでシェアしてくれると大歓迎です!
感想は私のTwitterアカウント宛てに送ってください。



(訳者注記)
1 ACID: ACID (コンピュータ科学) - Wikipedia
2 グリーンフィールド・ソフトウェア・プロジェクト: 他のシステムとの統合を気にすることなく、全く新しい環境のためにシステムをゼロから開発するプロジェクトのことを指します。

 
(関連情報)


 


この記事も読まれています!
tkybpp.hatenablog.com
tkybpp.hatenablog.com