Design Docの書き方
- 背景、目的 (Why?)
- 検討した別の方法 (alternatives considered)
- トレードオフ (Why not?: なぜ別の方法にしなかったのか?)
- 設計、アーキテクチャ (How?)
- メンバー (担当者やレビュワー) (Who?)
- セキュリティやプライバシーについての考察など
- 他プロジェクトとの関連性
- テスト,モニタプランなど
基本的には、ソースコードを見てもわからない部分をDesign Doc
に書いて、議論するのが一般的のようです。
Design Doc
は、Googleに代表される最先端の技術企業で取り入れられている設計ドキュメントのスタイル。
単にドキュメントの書式だけを指すのではなく、書いた後の使い方までを含めた『開発のやり方』につながっている
ドキュメント方式。
アジャイルなどの現代的なソフトウェア開発スタイルにフィットしているため、シリコンバレーのスタートアップ企業などで広く受け入れられている。
Design Docは、エンジニアがこれから開発しようとするソフトウェア設計の基本的な要点
- 何を:What
- 何のために:Why
- どのように:How
要点だけを書いて、それ以上詳細なことは書き過ぎないことが重要。
現代の開発スタイルでは、詳細な情報を得るにはソースコードを見た方が早いからです。
誰でも読める自然言語(日本語や英語)の文章で書くことが必要。
図やチャートを使ってもよいが、それらは文章を補助するものという位置付け。
図やイラストだけの資料だと、しばらく時間がたってから見ると正確な意味が分からなくなってしまう
ことがある。情
報の正確さや再現性の高さでは文章が一番。
思考の道具 - としても役立つドキュメント
Design Docの最初の読者は設計者自身。
他のドキュメントと同様に関係者に公開して情報共有に使う役割もあるが、設計しているエンジニア自身の「思考の道具」としても価値が大きい
ものになる。
システム設計は時間のかかる複雑な作業であり、関連するさまざまな要素について検討し、課題を解決し、それぞれの仕様を決定していかなければならない。
人間の脳は、そうした複雑な問題全体を一度に考察するのは苦手
ですので、何らかの形で分解して、途中経過を記録しながら作業を行う必要がある。
そのための手段としてもDesign Docはうってつ気になる。
Design Docは常に変化し、生きているドキュメント。
試行錯誤の途中のアイデアでもよいので、どんどん書き出してみて、何度も修正しながら仕上げる
ことができる。
Design Docの実例
具体的なDesign Doc
の実例。
日本語でDesign Doc
を公開されている事例が少ないため、英語版のものを引用。
英語が苦手な人も、項目タイトルだけ辞書で意味を確認してみれば雰囲気が分かる。
WebKit WebSocketDesign Doc(グーグル)
The Chromium Projects - Extensions
実例を見ると分かるように、Design Docに決まったフォーマットは無いが、記述される項目はだいたい似ている。
およそ下表に示すようなものとなっている。
- タイトル:このソフトウェアの名称
- 著者名:このDocを書いた人
- プロジェクトメンバー:開発に参加するメンバー
- 目的:このソフトウェアの目的
- 要求仕様:要求仕様書、機能仕様書などへのリンク(要求仕様の要点を書く場合もある)
- 背景:このソフトウェアを開発する背景・経緯など
- 既存のものとの相違点:既存品があるなら、それとの違いを書く
- 関連システム・仕様など:関連システムやその仕様書へのリンク
- ハイレベルアーキテクチャ(アーキテクチャ概要):システム全体を俯瞰した構成図など
- 各パート(モジュール・クラス)の概要:各パートの概要・責務・目的など
- 各パート(モジュール・クラス)の内部仕様・処理フローなど:データ構造、アルゴリズムなど
- 各パート(モジュール・クラス)の実装場所:ソース・ファイル名、実行形式の名称など
- 使用例:モジュールの利用例が分かるサンプルコードなど
- セキュリティ仕様・考慮事項など:想定される問題と、その対処方法などについて
- 既知の問題:事前に判明している問題・課題などを書く
- テスト方案:どういう観点で何をテストすればよいか、どのようにテストすればよいか
- 運用方法:運用時のポイント、監視の方法など
- 参考文献:参考文献へのリンク
- このDocの格納場所:リポジトリのパス、ファイルサーバのパスなど
- メモ:設計のヒントや気付いた点、関連情報など何でも
- 変更履歴:このDocについて、いつ・誰が・どのような変更をしたのか履歴を記述
これらの項目のどれを含むかどうかは作者の任意になる。
自分のプロジェクトの目的に応じて書くべき項目を選ぶ。
ただし、この表中の項目名に黒く付いているものは、ほぼ必須と考えてよい項目。
ほぼ必須の項目は以下になる。
- タイトル
- 著者名
- 目的
- 背景
- ハイレベルアーキテクチャ
- 各パートの概要
- 各パートの内部仕様
- テスト方案
Design Docを書く事前準備
Design Doc
をいきなり書き始めることができるケースはなかなか無い。
通常は事前に準備作業が必要。
それは、要求仕様の理解と要素技術や開発環境の理解になる。
事前準備と設計の関係をまとめたものを以下に示す。
要求仕様をよく理解する
ソフトウェア設計のゴールは 「要求仕様を達成する方法を明確にする」 ことなので、まずは要件定義書や機能仕様書などを熟読して、要求仕様をしっかりと理解する。
書類だけでは不十分な場合には、関係者とミーティングを行って確認することもある。あらゆる手段を使って粘り強く理解を深めることが大切。
ここで要求を深く理解しておけば、この後の設計で手戻りが減って楽に作業を進めることができる。
集めた情報はしっかりとメモしておく。
ここで先にDesign Docのひな型を作って、そこにメモを残す
という手もある。
要素技術について確認する
要求を実現するための手段についての確認。
今回の開発で初めて使う技術や手法・アルゴリズムなどがある場合に実施
する。
ドキュメントや解説書・サンプルコードなどを読んで
求めているものが満たされるかどうか確認。
手慣れた手法だけで実施する場合はこのフェーズは省略
してもいい。
前回の続き
Design Docを書く
いよいよ、Design Docを書いていく。
初めにやることは、システムに名前を付け、ドキュメントの冒頭の部分に署名し、そしてこのソフトウェアの目的やゴールを書くこと。
名前を付ける
不思議なことに、良い名前を付けると設計がはかどる。
そのシステムにふさわしい名前を付けて、表紙に記載
しましょう。
目的やゴールを書く
目的・ゴールの書き方
の基本形は 『このソフトウェアの目的は★★であり、◯◯を実現することがゴールである。』という定義文 のスタイル。
何か誤解を生じる恐れがある場合は 『なお、このソフトウェアには、××機能は含まない。』 といった形で、除外されるものを明確にすることもある。
目的・ゴールは、できるだけ明確に書いておくことが重要。
この後の設計で迷ったときに、ここに立ち戻って判断することもあり、曖昧なままだと設計が迷走する原因
になる。
背景を書く
なぜこのようなソフトウェアを開発することになったのか、その動機や経緯
などが分かると、あとで読む人がより深く設計の意図を理解できる
ので、可能なら書いておく。
システム概要を書く
ここからは具体的な設計内容。
文章の構成は『全体から部分へ』
という順序で書くのが原則になる。
まずは全体の概要を書く。
このシステム(モジュール)の最上位レベルの姿を記述する。
英語ではHigh-Level Architecture(ハイレベルアーキテクチャ)
と呼ばれる。
システム構成図、クラス図などの図を添えると、より分かりやすくなる。
システム各部の設計を書く
ソフトウェア各部の設計を項目別に記述していく。
その項目について、目的、データ構造、アルゴリズム、インタフェース
などを端的に記述する。
必要なら疑似コードや各種のチャート
などを加えてもいい。
どうしてそのような設計にしたのか、設計判断の理由を書き加えておくと別の読者の役に立つ。
なお、設計項目を決めていく際には、できるだけ一貫した方針で項目を決めるのが通例。
方針は基本的には以下の2つになることが多い。
- 機能で分ける
- モジュール・画面などの物理的配置で分ける
どちらが良いかはシステムの目的や設計の説明のしやすさなどから判断して決める。
小・中規模のシステムでは機能で分けることが多いと思い。
大規模なシステムでは、まず配置で分けてからそれぞれの機能を設計していく場合もある。
その他の項目を書く
テスト方針や、設計したライブラリやAPIなどの使用例、参考文献など、そのプロジェクトの目的に応じて必要だと思う項目を適宜考えて書き加える。
リポジトリやクラウドに格納して共有
一通り仕上がったDesign Docは、チームで共有する。
他のメンバーにレビューを依頼
してコメントをもらう。
複数の目でチェックすることで、抜け漏れや別の良いアイデア
が見つかるかもしれない。
Design Docの書き方のポイント
結果だけではなく理由・背景を重視
従来の設計書
、設計の決定事項だけを記述する
ことも多々あったと思うが、Design Docでは、その決定に至った理由や背景(何のために、何を、なぜ、どのように)を重視して記述する。
逆に、従来型の設計書に求められた細かなコードレベルのインタフェース仕様
や、データベーステーブルの詳細定義などを記述することにはこだわらない。
ソースコードとペアで活用することを意識
Design Docは、ソースコードとペアで活用することで最大の効果を発揮する
ことを狙っている。
そのため、Design Docに書く内容がソースコードやコメントと同程度なら意味が無い。
Design Docにはソースコードだけでは伝えにくい情報
を書かなければいけない。
情報の『詳細さの度合い』
のことを情報の『粒度(りゅうど)』
というが、粒度の小さな情報(=詳細な情報)
はソースコードとそのコメントで十分です。
Design Docには、それよりも粒度の大きな情報、すなわち、設計の意図や背景
、他のモジュールやシステムとの関係性などを書かなければいけない。
※ Design Docにはソースコードを包括する情報や、背景情報
などを書く
長文は必要ない
Design Docは文学作品では無い。
項目をうまく区切って、テンポ良く読み書きできる文章を目指す。
長文も必要ないので、箇条書きや表などをうまく活用
してシンプルで端的な文書
作りを目指す。
ただし、キーワードが並んでいるだけで、読んでも意味が分からないのはNGです。
『読んで分かるけれども、無駄がない』文章が理想になる。
見せかけの納品用ドキュメントではない -- Design Docを活用した開発
Design Docは見せかけの納品用ドキュメントでは無い。
プロジェクトの中心に置いて実践的に活用する
ことで真価を発揮する。
実際の開発プロジェクトに適用するときの使い方やポイントについて述べる。
どんな場合に書くのか
Design Docをどういう場合に書いて、どういう場合に書かないのか?
基準となるのは 『このソフトのプログラマーが自分だけであり、かつ実装時間想定が2~3日以内』の場合にはまずDesign Docは書かない。
ここまで小規模であれば書かなくても大した問題にならない。
それ以外の場合(複数のプログラマーが関わっている、または実装に4日以上かかる)
にはDesign Docを書くように心掛ける。
いつ書くのか
要求仕様(要件)が一通り決まった後、実装フェーズの前に書く。
1~2週間かけて書くことが多い。
それ以上時間がかかる場合は、 単独で書くには大き過ぎる恐れ
がある。
範囲を分割して、Design Doc自体を分割して作ったり、複数のエンジニアで分担して書いたりする
ことを検討する。
どう管理するのか
Design Docはバージョン管理できる環境に置く。
Markdownなどのプレーンテキストで作成
してソースコードと一緒にGitやSubversionのリポジトリに置いたり、Google Docで作成したりする方法。
メンバーがいつでも参照したり修正したりできることが大切。
常に最新に保つ
実装を進めていく中で設計変更が必要になる
ことがある。
その場合はすぐにDesign Docを修正する。
緊急の場合をのぞき、Design Docを修正するまではコードを修正しないのが得策
です。
コードレビューの必須資料にする
Design Docのご本家、Googleではコードレビューが制度化されており、その際必ずDesign Docの提出が求められる。
ReviewrはまずDesign Docを読み、それからコードをレビューする。
この方法は非常に質の高いソフトウェアの開発につながることは容易に想像がつく。
テスト計画を前倒しにする
Design Docがあれば、実装と並行してテストケースを作る
ことができる。
少なくとも 「どういうテストを、どれぐらいの規模で実施しなければならないか」について基礎的な見積もりはできる。
ユーザーマニュアルなどの作成を前倒しにする
Design Docがあれば、実装と並行してユーザーマニュアルやPR資料を作ることができる
場合もある。
これにより、営業や広報チームはいち早くマーケティング活動を開始
できる。
「ソフトウェアを設計する」ことの意味
当たり前の話だが、Design Docを書くには設計という作業
が必要。
最後に、「設計する」ことの意味について、あらためて確認
しておく。
設計するとは、何をすること?
ソフトウェアの設計の本質は今も昔も変わらない。
それは『データ構造』『アルゴリズム』『インタフェース』
を目的に応じて適切に決定すること。
時代と共にプログラミング言語や実行環境・開発方法論などは変化するが、上記の設計の本質は変わっていない。
つまり、これらの本質をつかんでおけば、今後もさまざまな場面に適用することができる
。
以下では、その概要を簡単にまとめておく。
データ構造の設計
「データ構造の設計」
とは、データベースのスキーマ
やファイルフォーマット
、オブジェクト指向を適用する場合のクラス構造、変数の型や配置
など、システム上でデータを格納する方法や形式を決定する。
アルゴリズムの設計
「アルゴリズムの設計」
とは、上記のデータ構造にアクセスして、何らかの計算や変換・転送などを行うプログラム上の手順や方法・仕組みを決定する。
さらに、アルゴリズムは以下の2つに分けると考えやすい。
- 処理アルゴリズム設計
- 制御アルゴリズム設計
処理アルゴリズムの設計
「処理アルゴリズム設計」は、入力データを出力データに変換するまでの計算手順を決定することです。
フローチャートやUMLアクティビティ図などを使って表現する
ことができる。
実装上は一つのメソッドや関数、APIなど
の形を採ります。
制御アルゴリズムの設計
「制御アルゴリズム設計」は、前記の処理アルゴリズムがいつ・どのような条件で実行されるのか、その順序やタイミングについて決定すること。
状態遷移図や、タイミングチャートなど
で表現することができる。
実装上は、メインループ
やイベントディスパッチャ
などで現れるが、最近はアプリケーションフレームワークの中にあらかじめ内蔵されていることも増えたので、フレームワークやミドルウェアを選択することもこの設計の範囲
となる。
インタフェースの設計
「インタフェースの設計」は、システム内・外で2つ以上の要素が交わる境界部分の仕様を決定すること。
Web APIやBLEなどのデバイス・ノード間の通信のプロトコル
、オブジェクト指向言語でのオブジェクトの呼び出しインタフェース
などがある。
ユーザーとシステムの境界も含めて考えると、ユーザーインタフェースもインタフェースの一種
になる。
画面レイアウトや操作方法などを決定することも含まれます。
分割と階層化をうまく使う
データ構造、アルゴリズム、インタフェース、
どれもさまざまな要素が組み合わさって成り立っているのが普通。
一気にそれを設計しようとするのは無理があるため、分割や階層化を行って適切なサイズで区切って設計していく。
複雑な問題を分割して解決する、これはエンジニアの基本スキルの1つ。
デザインドックで学ぶデザインドック
いわゆる設計書でだが、エンジニアによって書かれ、書いた本人またはチームによって実装される点と、技術的な詳細を明確にし技術的な議論をすることにフォーカスがある点が特徴。
他人に開発を依頼するための設計書や、既存のシステムを解説するための文章とは性質が異なる。
デザインドックを書くことの利点としては以下のような点がある。
- 開発を始める前に全体のシステムを考察する機会を得る
- 文章化することで、曖昧な部分が明確になる
- 早い段階でチームメイトや専門家、関係者からフィードバックを得る機会を得る
- システムの設計について明確な承認を得られる
- 新しいメンバーがシステムの概略を理解する手助けになる
前回の続き
Design Docのサンプルを書いていく
タイトル - Design Doc of Design Doc
目的 - Goal
デザインドックを導入することで、新しいシステム・機能の設計に関する技術的な議論を円滑にし、開発の早い段階でのフィードバックを容易にする。
また複雑な機能を設計する際、ドキュメントの形で明確化することで曖昧な部分、考慮が十分でない部分をなくす。
Non Goals
- 完璧な設計書の作成
-
デザインドックで書かれたシステムは、デザインドックを書いた本人またはチームによって実装される
ため、概略に注力し、議論の必要のない詳細は省き、実装の詳細はコードレビューなどで議論
する。
-
- 要件定義
-
簡単な要件ならばデザインドックでも定義できるが、要件が変更されるとそもそもシステム全体のデザインを変更する必要がある
ため、要件定義はデザインドックが書かれる前にある程度固まっている必要がある。
-
背景 - Background
ある機能やシステムをデザインする際、同じ機能を実現するのでも様々な方法
があり、エンジニアは常に選択を行いながら開発
を行っている。
しかしたとえ短期的に同じ機能が実践できる設計でも、長期的に見た場合は以下の4点などが大きく異なり、いずれかの問題の結果システムを再構築することもある。
- 拡張性(Extensibility)
- 安定性(Reliability)
- スケーラビリティ(Scalability)
- 保守性(Maintenancebility)
Google で使われていることで有名になったデザインドックは、エンジニアによって書かれる設計書であり、書いた本人またはチームによって実装される
と、技術的な詳細を明確にし技術的な議論をすることにフォーカスがある点に特徴
がある。
概要 - Overview
デザインドックは大まかに以下の章によって構成される
- Goal:デザインされるシステムの目的
- Background:前提になる知識や参考になるページ、専門用語の定義。
- Overview:概要とシステムの構成など。
- Detailed Design:設計詳細。
- Caveats / Security Concerns / Privacy Concerns:プライバシーやセキュリティーなどの注意点
デザインドックを書くプロセスはチームによって様々だが、概ね次のようになっている。
-
まず最初にドラフトとしてGoal や Overview などを埋めたあと、数人に共有し最初のフィードバックをもらう。
-
さらに詳細を埋めたあと必要であれば関係者やチーム内レビューを行い、
承認が得られれば開発
に移る。 -
開発によって
デザインドックが書かれている内容と実装が次第に乖離してくるのを防ぐ
ため、定期的にアップデートすることでメンテナンスする。
前回の続き
設計詳細 - Detailed Design
構成
デザインドックの各章立てについて解説する。
- Goal
- Non Goals
- Background
- Overview
- Detailed Design
- Sub sections
- Caveats / Security Concerns / Privacy Concerns
- Alternatives Considered
Goal
1~3文程度の短い段落で、デザインされるシステムの目的を述べる。
要件を定義するとき、後述するPRDが存在すればリンクを張り
、存在しなければ専用の章を設ける。
Goal が間違って広く捉えられると、議論が範囲外を超えてしまい、毎回軌道修正する必要
がある。
そんなとき Non Goals として議論やシステムの目的範囲を狭め、明確にする
ことで、無駄な議論を省くことができる。
Background
前提になる知識や参考になるページをリストする。
中で使う専門用語や略語も定義
して、意味を明確
にしておく。
デザインドックはシステム全体の議論
を行うため、さまざまな人からフィードバックをもらう必要
がある。
たとえばフロントエンドとバックエンドの両方に改修が必要な機能の場合、両方のチームからレビューしてほしいが、それぞれのチームは自分のチーム外については詳しくない。
そのような場合でも、関係者が全体を読んで理解できるように情報を補足するためにも、Backgroundは重要。
Overview
概要や目的を3,4段落で説明する。
システムが複数のコンポーネントからなる場合、概略図を書く
と読者の理解が容易になる。
Detailed Design
詳細設計。
必要に応じて数ページ程度に収めるのが理想。
章立てをきちんと行い、読者が必要な情報にたどり着けるようにすることが重要。
あまりに長くなる場合は小さい機能を別のデザインドックとして独立させ、議論を分けることで読者の負担も減る。
Alternatives Considered
考慮されたが選ばれなかった設計をその利点・欠点も含めて書いておくことは、見逃されがちであるが重要である。
Caveats / Security Concerns / Privacy Concerns
Caveats にはシステムの注意点
などを書く。
セキュリティーやプライバシーの懸念
に関しては、専用の章を設けることで、議論を明確化し、ローンチの前に必ず解決する。
前回の続き
その他
APIのデザインなどの、例があるとわかりやすいが Detailed Design に含めるには長すぎる場合は Example の章をAppendix としてつけると全体が読みやすくなる。
テストのプロセスが重要である場合は Test Plan の章を含めることで、どのようにテストされるか議論することが可能になる。
ツール
デザインドックを書くツールは、章立てされた文章が残せて、フィードバックが受け取れるツールならば何でも良い。
Google Docs
最もメジャーなツールは Google Docs
であり、レビューの際はフィードバックをコメントの形でもらうことになる。
利点としては以下の点が挙げられる。
- コメントのハードルが低い
- エンジニアに限らずだれでもコメントを受け付けられる
- 共有範囲を自由に変更できる
- 同時編集可能
- 図の挿入が容易
欠点としては以下の点がある。
- 変更履歴が見づらい
- URLを知っていないと探しづらく、golink を使うなどの工夫が必要
GitHub + Markdown
Markdown 形式等のプレインテキストで書き GitHub 等のバージョン管理&レビューシステムを使ってフィードバックを貰う方法もある。
利点としては以下の点が挙げられる。
- 履歴が見やすい。それぞれの行をいつだれが変更したか追跡可能
- シンタックスハイライト
- コードと同時にレビューが可能
- コードと同じレポジトリーで管理することで、見つけやすい
欠点としては以下の点がある。
- エンジニア以外がコメントするハードルが高い
- PRがないとコメントがつけられず、しかも変更した行に限られる。
- 図を書くとき、コードで書くか画像をアップロードする必要がある
いつ書くべきか
デザインドックをいつ書くべきかについては明確な基準は無い。
- 同僚・チームメイトのフィードバックが必要
- チームメイトがそのシステムの開発に後から加わるとき、コードを読むだけでは十分な理解できない、もしくは時間がかかりすぎてしまう
- デザインに複数の選択肢があり、後日自分が見返したときに現在のデザインを選んだ理由がわからなくなりそう
などの条件を1つでも満たした場合、デザインドックを書くことをおすすめする。
プロセス
デザインドックを書くプロセスはシステムやチームによって様々だが、概ね以下のようなステップを経る。
-
ドラフト
とりあえず最初のドラフトを書く。Goal と Overview、特に議論したい Detailed Design の章を書いてしまえば十分である。まだ書いてない章は TODO コメントを残しておくと、「まだ書いていない」のか「書くつもりがない」のかわかって読者に優しい。 -
最初のフィードバック
チームメイトやメンターなどに共有し、フィードバックに基づいて更新していく。特に Google Docs や GitHub PR のコメントは本文には表示されないこともあるので、できるだけ同じフィードバック・質問が来ないように本文に反映させていく。たとえば読者が目的を外れた点について聞いてきたら、Non Goals をアップデートしたり、背景についての質問があれば Background に追記する。 -
関係者レビュー・チームレビュー
開発がチーム内で完結するような簡潔なデザインドックであれば、このステップは飛ばす。
必要があれば関係者やより広いチームに共有する。デザインドック文化が根づいていれば、自分の範囲外でも有用なフィードバックを送ってくれるデザインドックのプロのような人がいるので、その人のことは覚えておいて、別のデザインドックを書いたときも直接その人に送ると、より自分のデザインドック力が高まる。 -
開発
必要な人からのレビューを大方受けたあとは実装に移る。この際にデザインの時点では見逃していた点、想定外の課題に相対することはよくあることであり、その都度デザインドックをアップデートし、必要ならレビューを頼む。 -
メンテナンス
システムが改修され続けるたびに、デザインドックが更新されるのが理想だが、実際は放置されることも多い。デザインドックは実装されたあともシステムをざっくりと理解するために役立つため、チームに新しい人が来たタイミングでアップデートしたり、大きくシステムが変わる際には新しいデザインドックを書くのが望ましい。
前回の続き
注意事項 - Caveats
デザインドックのスタイルは一つではない。
このデザインドックでは著者の経験に基づく、効率的なデザインドックの書き方について述べたが、エンジニアによってそれぞれデザインドックの書き方は異なっており、正解は一つではない。
自分に合ったやり方を模索することが重要である。
すべての文章をデザインドックの形式で書く必要はない
例えばこの文章は「デザインドックを広めるための文章」であるが、議論よりも情報の伝達に重きが置かれるべきであり、デザインドックのフォーマットは必ずしも適さない。
この文章をデザインドックとして書いている理由は単純に「デザインドックのデザインドック」というメタ的な面白さを追求した試みのためである。
最新の情報を反映していない
デザインドックはデザインを議論し、明確な間違いを避けたり、設計者自身が曖昧になっている点を明確にするためのもので、メンテナンスに重きを置かれていない。
読者が疑問に思ったときにや間違いを見つけたときにアップデートする必要がある。
デザインドックに時間を書けすぎない
「完璧な」デザインドックを書こうと時間を使いすぎてしまうことは、「早い段階でフィードバックをもらい議論すること」を目的としたデザインドックの目的から逸脱している。
できるだけ早い段階でレビューしてもらい、実装しなければわからない点があれば早めに実装に移るのも手である。
代替案 - Alternatives
技術的な内容に関して文章を書くとき、デザインドックが適切なフォーマットであるとは限らない。
PRD
PRD(Product Requirements Document, 製品要求仕様書)は、製品が満たすべき仕様をまとめたものである。
一般的にPRDはエンジニアがシステムをデザインドックで設計する前に(少なくとも同時に)書かれるべきものである。
デザインドックを書いたつもりが、製品についてばかり議論されるとき、必要なのはデザインドックではなく PRD である。
コードレビュー
APIの細かな定義や動作、使うアルゴリズムやその実装などは、実際に作り出すまでわからないことが多く、すべてを事前に決めることは不可能である。そのような技術的詳細は、実際に実装したあとコードレビューを行うほうが建設的で具体的な議論ができる。
Design Proposal
システムが「デザインドック」と呼ぶにはあまりにもシンプルだが、フィードバックを得たいとき、Detailed Design 以下の章を除いたデザインプロポーザルというフォーマットを準備しておくと、気軽にフィードバックを受けられる
仕様書の参考例
一般的な仕様書とは
一般的に製品やサービスなどが満たすべき条件や内容を明確化し、まとめた書類のことを「仕様書」と呼ぶ。
それを実現するものを設計書と呼ぶのが概念です。
一方で、仕様書の具体的な定義は曖昧なことが多く
、プロダクト開発において関係者間での認識齟齬や仕様のもれを防ぐためのドキュメントを一般的にさしている
ことが多い印象。
具体的に仕様書の対象となる内容
システム開発のV字モデルにおける要件定義書と基本設計書の一部であることが多い。
大きく分類すると、以下になる。
- 要件定義:
サービス概要
、機能や性能概要
を定義。 - 基本設計:
外部設計
を行う。目に見える機能
についての仕様。 - 詳細設計:
内部設計
。バッチ処理やデーターベース構成
などユーザーの目に見えないもの
を定義
基本設計の具体的な成果物の一例
詳細設計の具体的な一例
最低限必要な仕様書の主な項目について
仕様書によく書かれる主な項目
は以下の通り。
要件定義の一部と基本設計の一部を書いているものが多い。
仕様書の項目
- 仕様書のステータス、担当者、各種リンク
- 目的
- KPI
- 概要
- 機能一覧(複数機能ある場合)
- 画面遷移(複数画面ある場合)
- 画面イメージ+機能の仕様
- 分析ログ
仕様書のイメージ
ポイント
- ドキュメントのステータスとFigmaやチケットへのリンクの作成
- KPIとログがリンクするように記載
- 画面が複数ある時は画面遷移を添付
- 仕様記載について
- 画面名やセクション名は認識ずれを起こさないために明記
- ボタンは画像なのか、テキスト表示なのかを記載。具体的な表示方法(右寄せや縦横固定、透過など)はFigmaにコメントで書く場合も多い
- テキスト情報の表示の場合は、上限文字数や上限を超えた時の処理の記載
- 動的に表示するか静的に表示するかの確認
- 例) ランキング表示について、バッチで1日1回更新なのか、読み込みのたびに表示なのか
- ユーザー入力がある場合
- 分岐、入力情報の上限文字数や文字の種類、バリデーションチェックを記載
- タップ時の注意
- タップエリアの明記
- エラーチェックを記載
- AndroidとiOSでページ遷移の種類がことなるので明記
- トライアル機能なのか継続的に使う機能なのかの意識合わせをする
- 例) 決済機能などは継続的に使うが、新しいキャンペーンなど一度トライアルでやるものなのか、継続的なのかによってどこまで作り込むかが異なるため
- 要件定義
- 仕様書
- 設計書
要件定義 - Requirements Definition
出来る、出来ないはともかく、作って欲しいシステム・機能を定義。
どちらかというと依頼側が書くものだが、慣れていない場合は、開発側がヒアリングシート等を使って定義する。
依頼側「うちのECサイトも、アマゾンみたいにしたいねん」
開発側「ええ、Amazonみたいにですか!?」
依頼側「そうそう、この商品を買った人は、こんな商品も買ってますみたいな奴!」
開発側「ああ、リコメンド機能が欲しいのですね…。」
仕様書 - Specifications
要件・要望
は曖昧な部分が多いので、より具体的に、どんな物を作るか?どんな機能を持たせるか?を定義する。
作る物と作らない事を明確にする。
テスト仕様書もココで書く(何ならOKで、何ならNGなのか?)
逆に言うと「それ、どうやって作るの?」みたいな事は、このフェーズでは定義しない。
※とは言っても、明らかに無理な物はダメなので、実装・設計をイメージ出来ない人には無理。
設計書 - Design Document
仕様書で定義された仕様を、具体的にどうやって作るのかを設計(定義)。
画面設計・DB設計・画面遷移・MVCモデル・UML図などなど具体的な手法を使う。
- 外部設計:ユーザに見える部分
- 内部設計:システム的な処理
さらに外部設計・内部設計という分け方があり、外部=ユーザに見える部分・内部=システム的な処理、という風に分けたりもする。
実例
要件定義 - Requirements Definition
朝、電車が遅れたら、スマホに通知する
仕様書 - Specifications
- 朝とは具体的には?
- 時間帯指定できるのにする?平日のみにする?
- 指定方法は路線?駅?複数指定OK?
- 通知方法はメール?アプリ?電話?
- 設定画面はどうする?
- そもそも遅延情報は、どこから取得する?
など、具体的な機能を決める。
設計書 - Design Document
Django+MySQL
で作る。設定画面は無し(設定ファイルのみ)
サーバを立ててcronを使用、朝6-9時の間に一分毎にTwitter検索する。
「路線名+遅延」で検索して、一定数(10件)を超えたら、指定されたメールに通知する。
GoogleのDesign Docsから学ぶ
- Design Documentと聞くと何を想像するか
- 一般的にDesign Documentが指すのは設計書であることが多い
- 設計書、簡単に説明するのであればソフトウェアを
「どうやって作るの?」を説明したドキュメント
です - Googleでは
ソフトウェアエンジニアリング文化
における重要な要素として、今回お話ししていくDesign Docs
と呼ばれるものがある
Design Docsとは?
Design Docsとは、開発者がコーディングに着手する前にソフトウェアシステムまたはアプリケーションの開発する人が作成するドキュメント。
ソフトウェア設計における仕様書や設計書とは別物と捉えた方がよい
仕様書、設計書は作成した上でのDesign Docsの作成となる。
このドキュメントには、高レベルの実装戦略
と主な設計の決定事項がまとめられて
おり、設計において考慮されたトレードオフに重点を置いて文書化される。
ソフトウェアの重要なポイント
ソフトウェアを開発するエンジニアにとって重要なことは、コードを書くことではなくソフトウェアによってある問題が解決すること。
設計書のようなテキストを使用するということは、プロジェクトを進める中での初期段階で問題を解決することができるツールになる。
なぜならば、実際のコードよりも簡潔で理解しやすく、当事者にとってある問題とその解決策を高いレベルで伝えることができる
為。
Design Docsを使うことで嬉しいこと
- 変更を加える際に、設計上の問題を早期に特定することで、手戻りが少なくなる
- 組織内の設計に関する合意形成を達成することができる
- 懸念事項を確実に考慮できる
- ハイレベルなエンジニア(リードエンジニアとか)の知識を組織に浸透させることもできる
- 設計上の決定に関する組織の基礎を形成することができる
- ソフトウェア設計者の技術知見の中で要約された成果物となる
前回の続き
Design Docsの中身
Design Docsについては、先に述べたようにソフトウェア設計における仕様書や設計書とは別物であるので、がちがちな形式はない。
しかし、ルールが1つだけ存在する。
Design Docsを作成するプロジェクトにとって最も意味のある形で書く
こと。
コンテキストとスコープ
ここでは、新しいシステムをなぜ構築するのか。
実際に何が構築されようとしているのか
をざっくりまとめる。
要件書ではないので、簡潔にするのがポイント。
客観的な背景と事実
に焦点を当てる必要がある。
目標と目標としないこと
システムの目標が何か。そして何が目標ではないのか。
それを箇条書きにする。
目標ではないこと、というのは「システムがクラッシュしてはならない」などの否定されたものではなく、目標である可能性があるものの、明示的に目標ではないことが選択されていることとする。
Design Docsにおけるデザインの本体
概要
- Design Docsは、
ソフトウェアの設計の中で決めたトレードオフ
を書いていく為のもの - 長期的に価値のあるドキュメントとなるよう作成していく
- 具体的には、上記でコンテキスト(ここで事実が述べられ)、目標と目標としないこと(ここが要件にあたる)があるので、それをもとに具体的なソリューションを提案し、なぜそのソリューションがある問題を解決できるのかという理由を記述していく
- しかし、前にも言ったようにDesign Docsはざっくりしたドキュメント。なので、問題の解決策も踏まえ柔軟性を含めながら書いていくことがポイント
- また、設計を実際にどのように記述するのかという明確な指針はない
- しかし、それだけだと最初は迷ってしまう
- なので、いくつかのベストプラクティスやこんな感じに書くのがいいよねというものがある
システムコンテキスト図
多くのドキュメントでは、システムコンテキスト図が非常に役立つ。
このような図を使用することでシステムを拡張する際に分かりやすいですし、読みやすい。
前回の続き
API
- 設計中のシステムが既にAPIを公開している場合は、そのAPIを記載することを推奨
- しかし、めんどくさがってI/Fやデータの定義をコピペしたくなるのですが、これはオススメしていない。
- なぜかというと、それらをコピペしたところでただ冗長なドキュメントが増えるだけで、かつそれらの情報が古くなる可能性を秘めている。
じゃあ何を記せば良いか
それは、設計とのトレードオフに関連する部分に焦点を当てた内容を記載する。
データストレージ
- データを保存するシステムでは、保存がいつ、どのような形で発生するのかを議論する必要がある。
- ここでも完全なスキーマ定義をコピペするのではなく、やはり設計とのトレードオフに関連する部分に焦点を当てた内容を記載することとしている
コードと疑似コード
- Design Docsには、新しいアルゴリズムが記述されている以外は、コードや擬似コードを含めない。
- あとは、設計の実現可能性を示す必要があればプロトタイプのリンクを記載する。
解決策における制約の度合い
- Design Docsにおいてソフトウェアの設計へ影響を与える主な要因の1つは、設計するソリューションの制約の度合。
- 解決策が明確に定義されているが、目標を達成するためにその解決策をどのように組み合わせればよい(新規のソリューション同士や既存のシステムに対する拡張等で)のか分からない場合があったとします。
- これは変更するのが難しいですし、もし既存のシステムへの拡張をするとなった場合、既存のシステムがレガシーにより特定の制約がかかってしまうというということを指しています。
この場合においてもDesign Docsでは、複数の解決策を列挙していき、想定され得るすべてのトレードオフを考慮して最善の方法を選択することに焦点を当てる必要があります。
検討した代替案
- ここでは、検討した結果、推しの設計と同様の結果を達成できる代替の設計を列挙していきます。
- それぞれの設計においてのトレードオフとそのトレードオフの結果から推したい設計を選択する際の最終的な決定に繋がったのかに焦点を当て記載します。
- 最終的に選択されなかったソリューションについては、簡潔に述べて良い。
- ただ、選択されたソリューションがプロジェクトの目標と代替のソリューションを考慮して最適である理由を明確に示す必要があることだけが重要です。
懸念事項
ここでは、セキュリティやプライバシー、などの懸念事項が考慮されているのかを示します。
これらの懸念事項が設計にどう影響を与え、どのように対処するのかを説明します。
そのため、チームはこれらの懸念事項を標準化する(設計全体を通して懸念事項を考慮する必要があるため)必要があります。
Joelの機能仕様書