
安全安心にソフトウェア開発を行うためのDesign Doc導入ガイド
みなさん、コードを書く前に設計書を書きますか?
書くか書かないかは人それぞれだと思いますが、「設計」というプロセス自体は意識的であれ無意識的であれエンジニアであれば全員やっていることだと思います。
今回は設計プロセスの改善という文脈で私たちがDesign Docという仕組みを導入したことについて共有しようと思います。もし同じような状況を経験している人がいたら参考になれば幸いです。
導入の背景
まずは導入するに至った状況からお話します。
私たちのサービスは、利用していただくユーザーの数が増加しています。それに伴って品質のハードルも上がってきました。サービスに障害が発生するとユーザーさんに大きな損害を出してしまうことになるからです。そこで今まで以上に安全にサービスを開発できる仕組みづくりが必要になりました。ですが、実現のためには大きく2つの課題がありました。
課題1. 開発スピードが徐々に鈍化してきた
迅速な機能追加が難しくなってきました。
理由としては、コードベースが増えてきており適切な実装を行うためにアーキテクチャのトレードオフを多角的に検討する必要が出てきたためです。
スピード低下の具体例を挙げると、プルリクエストをレビューする際に改修範囲のボリュームが大きくてレビュアーが背景を把握しづらかったり、プルリクエストが解決する問題の共通認識が取りづらくてアプローチの妥当性をレビュアーが判断しづらい問題がありました。特に大規模なリファクタリングでは顕著に見られるようになりました。そもそも大規模なリファクタリングを避けるべきという論点もありますが、私たちは迅速な機能追加のためには継続的なリファクタリングが重要だと考えているので、この課題は改善する必要があると認識しました。
課題2. ステークホルダーが急激に増加したことによる情報共有の不足
プロダクトに携わる関係者が1年前と比較して3倍以上に増えました。そのため関係者同士の認識合わせをやりづらくなってきました。業務が専門化され、役割が細分化されていくなかで小規模のミーティングが各所で開催されるようになりました。その結果、全体像を把握できる人が非常に少ないという状況になりました。全体像を把握できる人もいますが、その人の頭の中にしか仕様がなく第三者に理解できる形になっていないので結局は把握してる特定の人に仕事の負荷が集中します。結果としてボトルネックが生まれてしまい仕事のスピードを下げます。私たちはこの課題も改善するべきだと考えました。
課題のまとめ
開発スピードの鈍化と情報共有不足のために、エンジニアが安心して仕事に取り組めない状態です。この状況を何とかするために設計プロセスの改善が必要と判断しました。結果としてDesign Docの導入に至ったわけですが、それまでにいくつか検討したことがありますので次はその話をします。
なぜ計画駆動型のアプローチを選ばなかったのか
ソフトウェア設計において歴史が長いのはウォーターフォール型開発モデルです。たくさんの会社で実践されてきたプラクティスであるウォーターフォールモデルをなぜ採用しなかったのか話します。
ウォーターフォールモデルは現時点で私たちの事業にフィットしない
私たちの事業は、市場へのフィット感がまだ不透明なので適合性を迅速に検証しつづける必要があります。そのために私たちはアジャイル開発を採用しています。私たちの現在の目的は、顧客に迅速な価値提供を行い、フィードバックを得ながら積極的に変化して市場の優位性を得ることです。そういった経緯から、安全性を担保しつつもあくまで競争力の獲得を優先したいという理由でウォーターフォールモデルを採用しませんでした。
もし私たちが原子力発電所や救急医療に関わるソフトウェアを開発しているなら計画駆動型のアプローチを取ると思います。高い確実性を担保しながら安全を第一に進めることが必要だからです。厳格な安全性を求められる環境では、ほんのちょっとした障害であっても大問題になります。ですから、障害が起きたときのコストが甚大になるシステムでは必然的に計画駆動型のアプローチを採用するでしょう。
たとえばの話ですが、旅客機のパイロットがデジタルメーターを見ながら運航している最中にエラーメッセージが誤表示されて緊急停止ボタンを押してしまったら大変なパニックが起きますよね。そういったシステムを開発するなら間違いなく計画駆動で進めます。
ウォーターフォールモデルの前提とする状況
ウォーターフォールモデルで設計工程を経て作成された設計書は、「あとはこの通りにプログラミングすれば目的のソフトウェアが出来上がる」状態を目指したものです。言い換えると、予想外の出来事が発生しないように完璧に設計しきることを目指すモデルです。
そのため、実装に入ってから仕様変更や抜け漏れが発生するとウォーターフォールモデルでは変更コストが大きくなります。変化への適応を前提とするアジャイル開発をする私たちにとってネックだと考えました。
なぜDesign Docを選んだか
さまざまに議論しましたが、最終的に、↓の内容を参考に導入するかどうか決めました。以下の引用箇所の太字は本記事の筆者によるものです。
厳格なガイドラインに従わないドキュメントは変更コストが低くて済む … アジャイル開発との親和性がある
Google のソフトウェアエンジニアリング文化の重要な要素の 1 つは、デザインドキュメントを通じてソフトウェア設計を定義することです。これは、ソフトウェアシステムやアプリケーションの作成者が、コーディングに着手する前に作成する比較的形式ばらないドキュメントです。設計書には、実装のアプローチと主要な設計上の決定事項が記載されており、その際に考慮されたトレードオフにも重点を置いて文書化されています。
デザインドキュメントは形式ばらないドキュメントであるため、内容に関する厳格なガイドラインには従いません。
内容が短く、ステークホルダーへの情報共有に向いている … 情報共有不足を解決する
デザインドキュメントは、十分に詳細でなければなりませんが、忙しい人が実際に読めるくらいの短さが必要です。大きなプロジェクトでは約10〜20ページです。それ以上になると、問題をより管理しやすい単位に分割する方が理にかなっています。また、1〜3ページの「ミニデザインドキュメント」を書くことも可能です。これは、アジャイルプロジェクトでの段階的な改善やサブタスクに特に役立ちます。
開発者同士で頻繁に設計を検討し合える … 開発スピードの鈍化を解決する
計画が現実と衝突するとき、つまり、欠点や未解決の課題が浮き彫りになった時、あるいは設計が間違っていると判明した時、設計の変更が必要になることは避けられません。このような場合には、設計ドキュメントを更新することを強くお勧めします。経験則として、設計したシステムがまだリリースされていない場合は、必ず設計書を更新してください。
以上の内容から、開発スピードの課題と情報共有の課題の解消が期待できること、ならびにアジャイル開発との親和性からDesign Docを採用しました。
どのようにDesign Docを採用したか
開発者の足並みを揃える
まずはDesign Docの共通認識を取ることからはじめました。Webの記事を参考にしてエンジニア各自のDesign Docに対する見識を深めました。参考にした主な資料はこちらです。
Design Docを導入する目的について合意する
上記の参考資料をもとにエンジニア同士で話し合い、意見を出しました。以下のような意見が出ました。
開発完了までに数スプリントかかるときは作ろう
いくつかの実装案が考えられる、かつどれがベストなのか決めるのが困難なときは作ろう
技術的であったりドメイン的に新規のものや慣れていないものを扱うときは作ろう
シニアエンジニアにアーキテクチャの考察をしていただきたいときは作ろう
シンプルな機能は逆に Design Doc を書く必要はなさそう
これらの意見を課題に照らし合わせ、Design Docの導入目的を作りました。
エンジニアが安心して開発していくために、設計プロセスを改善する目的でDesign Docを作成します。これにより、実装前に設計の妥当性を検証したり、リスクの洗い出しを行いやすくなります。
具体的には以下の目的を持ちます:
1. 作ろうとしているもの、実現しようとしていることをステークホルダーと認識を合わせるため。ここでいうステークホルダーは、エンジニア・プロダクトマネージャー・社内外の関係者を想定しています。
2. 設計・実装方針に関してエンジニア間で合意を取るため。
Design Docはエンジニアがメインで書きます。サービスの企画を考えた人やプロダクトマネージャーが共同執筆者となります。
書く項目を決め、サンプルを書いてみる
参考にした資料から、必要だと思う項目をピックアップして雛形を作成しました。雛形の項目は以下となりました。
プロジェクトタイトル
背景
目的(プロジェクトのゴール)
やること
やらないこと
既存機能から何が変わるか
概要設計(システム構成図など)
詳細設計(開発タスクに落とせる程度に詳細に書く)
検討した代替案(トレードオフの関係で却下した他のアプローチを書く)
品質管理のプラン
操作ログや分析に必要な情報の保存方法
セキュリティの考慮点
関連資料へのリンク
概算見積もり
次に上記の雛形をベースにGitHubでMarkDown形式でサンプルを書いて、レビューして項目をブラッシュアップしました。
運用フォーマットを決める
いくつか検討しましたがGitHubかGoogle Docsかの2択で検討し、最終的にGoogle Docsを採用しました。以下が決定理由です。
同時編集できる
GitHubだと複数人で同時に編集できず、編集するたび担当者を指名してプルリクエストを出してレビューするコストがかかる。たとえば、スプリントプランニングした結果をDesign Docに反映するときなど、複数人でDesign Docを編集することは充分にありうる。そのため、同時編集できるツールは効率的である。
オペレーションの効率がよい
GitHubのアカウントを所有していない非エンジニアの関係者が存在する。Googleのほうがアカウント所有率が高く、アカウント追加発行などのオペレーションの手間が少ない。
ドキュメントとしての書きやすさがある
箇条書きをネストするときなど、GitHubのMarkdownエディタでは不便なケースがある。ソースコードを載せるときはGitHubのほうが便利だが、Design Docにコードを載せる機会は少ないと判断した。
Design Docを書くタイミングを決める
Design Docの作成基準となるリリースを定め、判断の属人化を防ぐことにしました。Design Docが継続的に運用されることを目指すためです。以下の3つを定めました。
問題が起きると多くのユーザー、業務に影響が出る機能のリリース
サービスの根幹となる機能に影響はないが、2週間以上の開発期間を要するリリース
プロダクトマネージャーなどのステークホルダーに確認が必要な機能のリリース
作成方法とレビュー方法を決める
雛形に沿ってDesign Docを書いたあと、Google Docsのメンション機能でレビューを依頼し、レビュアー全員のOKが出たら開発を開始するようにしました。なお、情報共有としてエンジニアの共有Slackチャンネルにポストするよう定めました。サービスがモノリシックアーキテクチャなので開発する機能の知識を広く共有することが現時点では有益だと考えたためです。
まとめ … Design Docを導入して何が変わったか
最後に、当初の課題を解決して安全安心に開発できるようになったか所感を書きます。この記事を書いてる時点では導入開始から1ヶ月ほどしか経っていないのでまだサンプルは少数です。そのため確証は持てませんが現時点での実感です。大きく2つ感想があり、情報共有不足が解消されている感覚と、アジャイル開発との親和性を感じます。
情報共有不足の解消
Design Docを書く前まではエンジニア側の視点のみで開発タスクを決めていましたが、Design Docを書くことでサービスを企画する人やプロダクトマネージャー、社内外のステークホルダーからフィードバックを貰えています。結果的にエンジニアの視野も拡がり、抜け漏れが防止できていることや概算見積もりの出しやすさを成果として感じます。
アジャイル開発との親和性
技術的な調査の結果をドキュメントにすばやくフィードバックでき、その結果をステークホルダーに共有して再度フィードバックをもらうといったループが回っている感覚がします。フィードバックループが回る状況は好ましいと感じます。
現時点のまとめ … 安全安心を実現できているか?
正直まだリリースまで行けてないので分かりません。
現時点の感触は「フィードバックループは回せているが、もしかして迅速な価値提供という観点では速度が以前より鈍化する可能性もある」という感じです。フィードバックが沢山出るのは嬉しいですが、思ったよりもドキュメントの作成自体に時間が掛かっているような体感です。すこし焦りを覚えています。
何かわかったら追加記事を書こうと思います。
補足 … 実装前に設計ドキュメントを書くことのメリットについて
調査の一環として、設計ドキュメントを書くことのメリットについて個人的に気になったのでCODE COMPLETEを参考にまとめたものを共有します。
実装前に設計ドキュメントを書くことのメリットについてCODE COMPLETEを参考に調査した結果を共有します。HewlettPackard、IBM、HughesAircraft、TRWなどの研究によると、実装を開始する前に欠陥を取り除いた場合は、プロセスの最後や、システムテストの最中や、リリース後に欠陥を取り除いた場合よりも、作業の手戻りが10~100倍少ないことがわかっています。

上記の表をグラフに表すと下記のようになります。

ソフトウェア開発では、欠陥が持ち込まれたらできるだけ早い段階にそれらを発見することで大きなメリットを得ることができます。実装前に設計ドキュメントを書くことが欠陥の早期発見につながります。
以上です。
ちなみにDesign DocなのかDesign Docsなのか表記揺れに迷いましたが私たちはDesign Docに統一しました。
長文な記事になってしまい申し訳ありませんでした。ここまで読んでいただいてありがとうございます。アジャイル開発で設計書を書くことに興味のある人はぜひ参考にしてみてください。
※ 引用した資料は全て秘匿情報を削除して掲載しています。そのため文脈がちぐはぐな箇所が見られるかもしれませんがご了承ください。