GoogleのDesign Docsから学ぶソフトウェア設計

# 概要

* Design Documentと聞くと何を想像しますか？
* 一般的にDesign Documentが指すのは設計書であることが多いのではないでしょうか。
* 設計書、簡単に説明するのであればソフトウェアを「どうやって作るの？」を説明したドキュメントです。
* Googleではソフトウェアエンジニアリング文化における重要な要素として、今回お話ししていく[Design Docs](https://www.industrialempathy.com/posts/design-docs-at-google/)と呼ばれるものがあります。

## Design Docsとは？

* **Design Docsとは、開発者がコーディングに着手する前にソフトウェアシステムまたはアプリケーションの開発する人が作成するドキュメントです。**
=> ソフトウェア設計における仕様書や設計書とは別物と捉えた方がよいです。
仕様書、設計書は作成した上でのDesign Docsの作成となるようです。

* このドキュメントには、高レベルの実装戦略と主な設計の決定事項がまとめられており、設計において考慮されたトレードオフに重点を置いて文書化されています。

### ソフトウェアの重要なポイント

* ソフトウェアを開発するエンジニアにとって重要なことは、**コードを書くことではなく**ソフトウェアによってある問題が解決することです。
* 設計書ようなテキストを使用するということは、プロジェクトを進める中での初期段階で問題を解決することができるツールになるのではないかと言っています。
* **なぜならば、実際のコードよりも簡潔で理解しやすく、当事者にとってある問題とその解決策を高いレベルで伝えることができる為です。**

### Design Docsを使うことで嬉しいこと

* 変更を加える際に、設計上の問題を早期に特定することで、手戻りが少なくなる。
* 組織内の設計に関する合意形成を達成することができます。
* 懸念事項を確実に考慮できます。
* ハイレベルなエンジニア(リードエンジニアとか)の知識を組織に浸透させることもできます。
* 設計上の決定に関する組織の基礎を形成することができます。
* ソフトウェア設計者の技術知見の中で要約された成果物となる。

### Design Docsの中身

**Design Docsについては、先に述べたようにソフトウェア設計における仕様書や設計書とは別物であるので、がちがちな形式はない。ただ、ルールが１つだけ存在する。**

それは、**Design Docsを作成するプロジェクトにとって最も意味のある形で書くこと。** です。

ただ、それだけだとDesign Docsを初めて作成する人は困ってしまいますよね。
なのである程度、有用なものとして構造は確立されています。

#### コンテキストとスコープ

* ここでは、新しいシステムをなぜ構築するのか。実際に何が構築されようとしているのかをざっくりまとめる。
* 要件書ではないので、簡潔にするのがポイント。
* 客観的な背景と事実に焦点を当てる必要があります。


#### 目標と目標としないこと

* システムの目標が何か。そして何が目標ではないのか。それを箇条書きにする。
* 目標ではないこと、というのは「システムがクラッシュしてはならない」などの否定されたものではなく、目標である可能性があるものの、明示的に目標ではないことが選択されていることとします。

#### Design Docsにおけるデザインの本体
##### 概要

![スクリーンショット 2022-06-22 14.55.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/63a4cab0-18c7-fd12-599a-cab53d21c2b2.png)

[=> 画像引用元](https://www.industrialempathy.com/posts/design-docs-at-google/)

* **Design Docsは、ソフトウェアの設計の中で決めたトレードオフを書いていく為のものです。**
* また、長期的に価値のあるドキュメントとなるよう作成していきます。
* 具体的には、上記でコンテキスト(ここで事実が述べられ)、目標と目標としないこと(ここが要件にあたる)があるので、それをもとに具体的なソリューションを提案し、なぜそのソリューションがある問題を解決できるのかという理由を記述してきます。
* ただ、前にも言ったようにDesign Docsはざっくりしたドキュメントです。なので、問題の解決策も踏まえ柔軟性を含めながら書いていくことがポイントです。
* **また、設計を実際にどのように記述するのかという明確な指針はありません。**

* ただ、それだけだと最初は迷ってしまいます。
* なので、いくつかのベストプラクティスやこんな感じに書くのがいいよねというものがあります。

###### システムコンテキスト図

多くのドキュメントでは、[システムコンテキスト図](https://en.wikipedia.org/wiki/System_context_diagram)が非常に役立ちます。

* このような図を使用することでシステムを拡張する際に分かりやすいですし、読みやすいです。

![スクリーンショット 2022-06-22 15.17.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/fc4b7c4a-2e8c-7ee7-76d3-581a678317ff.png)

###### API

* 設計中のシステムが既にAPIを公開している場合は、そのAPIを記載することを推奨しています。
* ただ、めんどくさがってI/Fやデータの定義をコピペしたくなるのですが、これはオススメしていません。
* なぜかというと、それらをコピペしたところでただ冗長なドキュメントが増えるだけで、かつそれらの情報が古くなる可能性を秘めているからです。

=> じゃあ何を記せというのか。
それは、**設計とのトレードオフに関連する部分に焦点を当てた内容を記載することとしています。**

###### データストレージ

* データを保存するシステムでは、保存がいつ、どのような形で発生するのかを議論する必要があります。
* ここでも完全なスキーマ定義をコピペするのではなく、やはり**設計とのトレードオフに関連する部分に焦点を当てた内容を記載することとしています。**

###### コードと疑似コード

* Design Docsには、新しいアルゴリズムが記述されている以外は、コードや擬似コードを含めない。
* あとは、設計の実現可能性を示す必要があればプロトタイプのリンクを記載する。

###### 解決策における制約の度合い

* Design Docsにおいてソフトウェアの設計へ影響を与える主な要因の1つは、設計するソリューションの制約の度合いです。
* 解決策が明確に定義されているが、目標を達成するためにその解決策をどのように組み合わせればよい(新規のソリューション同士や既存のシステムに対する拡張等で)のか分からない場合があったとします。
* これは変更するのが難しいですし、もし既存のシステムへの拡張をするとなった場合、既存のシステムがレガシーにより特定の制約がかかってしまうというということを指しています。

=> **この場合においてもDesign Docsでは、複数の解決策を列挙していき、想定され得るすべてのトレードオフを考慮して最善の方法を選択することに焦点を当てる必要があります。**

###### 検討した代替案

* ここでは、検討した結果、推しの設計と同様の結果を達成できる代替の設計を列挙していきます。
* それぞれの設計においてのトレードオフとそのトレードオフの結果から推したい設計を選択する際の最終的な決定に繋がったのかに焦点を当て記載します。
* 最終的に選択されなかったソリューションについては、簡潔に述べて良い。
* **ただ、選択されたソリューションがプロジェクトの目標と代替のソリューションを考慮して最適である理由を明確に示す必要があることだけが重要です。**

###### 懸念事項

* ここでは、セキュリティやプライバシー、などの懸念事項が考慮されているのかを示します。
* これらの懸念事項が設計にどう影響を与え、どのように対処するのかを説明します。
* そのため、チームはこれらの懸念事項を標準化する(設計全体を通して懸念事項を考慮する必要があるため)必要があります。

---

## Design Docsを使用する上でのTips
### Design Docsの長さ

* Design Docsは詳細である必要はあるのですが、忙しい人が読めるよう短くする必要があります。
* 大規模なプロジェクトでも、約10〜20ページくらいが適切のようです。
* それ以上になる場合は、問題を管理しやすいよう分割する方法を取ります。
* **また、1〜3ページの「mini Design Docs」を作成することもよいです**
* アジャイル開発においては、そのくらいのミニマムなDesign Docsになると思います。

### Design Docsを書くべきか / 書かないべきかの判断

* Design Docs自体を作成することは、開発を進める上ではかなりのオーバヘッドになります。
* そのため、Design Docsを作成するかどうかの決定は、Design Docsを作成することに伴う労力が作成のメリットを上回るかというトレードオフで判断します。
* **この決定をする際に中心にあるのは、問題の解決策が曖昧で、その問題自体が複雑なのか、ソリューションが複雑になりそうかを考えます。**
* そうした時に、**上記のようでなければDesign Docsを作成する価値はないです。**

また、他の判断ポイントもあり例えば、Design Docsを作成し始めたけど実際には実装マニュアルになっているといった場合です。
=> どういうことかというと、**トレードオフや代替案、設計を決めた説明を行わずに、「これが実装方法です」というだけならプログラムをすぐに書く方がよい為です。**

### Design Docsにおけるライフサイクル

* Design Docsにおけるライフサイクルは次になります。

**①: 作成し、見直し**
**②: レビュー（複数回の場合もある)**
**③: 実装と見直し**
**④: メンテナンスし、学習を行う**

---

#### ①: 作成し、見直し

* このステップでは、問題領域について知識が豊富な同僚にDesign Docsを共有し、議論し修正していく中でDesign Docsが安定したものになっていきます。(これをイテレーションする)

#### ②: レビュー

* このステップでは、Design Docsを共有し①とは違い幅広いさまざまなメンバーと共有し、レビューしていただきます。
* ただ、レビューは大きな価値を生む反面、オーバヘッドになりやすいステップなので、慎重に行う必要があります。

##### レビューの方法

* 簡易は方法としては、チームメンバーにドキュメントを送りつけ見てもらう機会を作るだけです。
* その後は、正式な設計レビューの場を(会議等)設け、その内容をより偉い人に共有しレビューいただきます。

**ちなみにGoogleの多くのチームでは、この目的のために定期的に会議が予定されており、エンジニアはレビューのために担当者を指名することができます。**

=> **このレビューよる価値というのは、組織のが持つ経験を設計に反映させる機会を形成することにあります。**
例えば、先に述べたセキュリティやプライバシー等の懸念事項を考慮が担保されるのは、このレビューの段階で保証されます。
また、問題自体が発見されることなく開発のライフサイクルに入った段階で発覚してしまうと変更を加えるのが難しくなってしまうため、影響を小さくすることができるというメリットもあります。

#### ③: 実装と見直し

* プロジェクトが進み、レビューにて設計に大きな変更が必要なさそうと確信が持てたら、実装に入ります。
* ただ、計画していた設計と現実の問題がぶつかった時、すなわち考慮不足/欠点/課題の浮き彫りが起きた時は、設計の変更が必要になります。

=> そんな時はDesign Docsの更新をすることを強く推奨しています。

* **また、設計したシステムがまだリリースされていなければ設計書の更新をするチャンスです。見直し修正することができます。**

#### ④: メンテナンスし、学習を行う

* Design Docsは、時間の経過とともに実際のシステムと乖離していく傾向がありますが、それでもシステムの作成を導いた考え方を知るための最もアクセスしやすい入り口です。
* なので、Design Docsを作成したら1年後, 2年後に読み直し、何が正しかったのか。何が間違っていたのかを考えましょう。これがエンジニアとしての成長するための学習方法になります。

### Design Docsを作成する際のチェック表

* 下記の質問のうち3つ以上チェックとなった場合はDesign Docsを作成することでメリットを得られるでしょう。

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

## まとめ

* 今回はDesign DocsについてGoogleのソフトウェアエンジニアだった[cramforceさん](https://twitter.com/cramforce)が[自身のブログ](https://www.industrialempathy.com/posts/design-docs-at-google/)でまとめた内容を翻訳し、分かりやすい形でまとめていきました。
* まとめながら思ったのが、このDesign Docsを前チームの優秀なエンジニアはやっていたなと思い出しました。
* チームはアジャイル開発で行っていたのですが、設計のタスクにおいてチームで利用していたアトラシアン社のconfluenceにページを作成し、ただ実装の内容を書いていくのではなく考慮点、トレードオフ、既存システムとの最適な組み合わせを踏まえ1ページにまとめチームでレビューしていました。
* とても分かりやすかったですし、チームとしても作成するシステムへの合意決定と後で思い返した時になんでこうなっているんだっけを説明できていてとても納得感がありました。
* なので、この**Design Docs**の重要性にとても共感した次第です。

# 参考/引用

https://www.industrialempathy.com/posts/design-docs-at-google/