Design Docs への思い
Message Passing での話題を契機に、色々な人が自身の Design Docs 観を共有していて、とても興味深く読ませてもらいました。普段「仕事を進める上で当たり前に必要なもの」として書いている自分に気づき、これを機に自分の Design Docs 観も言語化してみようと思ったのが本記事です。実践の一例を付け加えることが狙いであり、「Design Docs はかくあるべき」と主張するものではないです。
はじめに
「人によって思い浮かべる Design Docs 観が全然違う!多様で面白い!!」というのが話の出発点ですが、さすがに想定しているものが違いすぎると話が発散してしまうので、本記事では Design Docs を「ソフトウェアエンジニア (私) が何らかのプロジェクトやタスクを進める上で書く文書」としておきます。
次に私の立場を明確にしておきます。私はオープンソースのウェブブラウザ開発プロジェクト Chromium に従事しており、チームリードではなく IC (Individual Contributor) として活動しています。このプロジェクトには世界中に散らばった社内外の開発メンバーが参加しているため、基本的に Design Docs は社外の人も読むことを前提に書いています。私が主に開発しているものはウェブブラウザ上で使う JavaScript API やブラウザ内部のアーキテクチャで、一つのクライアント内で完結しているものが多いです。Design Docs は Google Docs を使って書いています。
morrita さんが主張されている「欠点 1: 想定されている問題領域の狭さ」は私も常々感じていて、テンプレートとして提供されているものはウェブブラウザの機能開発に対して大げさすぎるので、普段はテンプレートを無視して書いています。
Design Docs を書く目的
私が Design Docs を書く目的や心がけていることを整理すると次のようになります。
自分の理解の整理
解決したい問題やその方法を言語化することで、やること・やらないこと、わかっていること・わからないこと、将来障害となりそうなこと、などを洗い出してプロジェクトの解像度や理解度を高めます。プロジェクトを通して問題領域における専門性を獲得する上でこのフェーズが特に重要だと思っていて、時間をかけて練り上げるようにしています。これが不十分な状態で議論を始めてしまうと、自分の理解に自信を持てなくなり、レビューアーのコメントで右往左往することになってプロジェクトの手綱を握りづらくなると感じています。
ちなみに私はコードを書きながらじゃないとデザインができないので、プロトタイピングしながら Design Doc を書くというスタイルを取っています。Design Doc が書き上がる頃には大体動くものができていて、議論を通してこのプロトタイプを叩き上げて完成形にします。
有識者によるアドバイス
プロジェクトの方針やわからないことに対して有識者にアドバイスを求めます。有識者はプロジェクトの成否に関わる貴重なコメントをつけてくれることもあれば、重要だけれども本筋とは関係ないコメントをつけてくれることもあり、気を抜くと議論が乱立・発散しがちです。前述の「理解の整理」を通して Design Docs のスコープを明確にし、有識者に対して何を期待しているのかをしっかり伝えることが重要だと思います。
なお Design Docs はメーリングリストやチームチャットなどで共有しますが、本当に読んで欲しい人が見逃していることもあるので、名前付きメンションを飛ばしたり個別チャットでレビューをお願いしたりします。
議論の集約
コードレビューやチャット・メールスレッドなどで突発的に起きた議論を集約する場所として使います。特に社内での議論は社外の人が直接見ることができないため、Design Docs に転記して社外の人もコメントできるようにします。
ステークホルダーの合意形成
合意は暗黙的なものと明示的なものの二種類があり、有識者によるアドバイスを取り入れた時点で合意形成とみなす場合もあれば、稟議書的にステークホルダーに承認印 (LGTM) を書き込んでもらう場合もあります。影響範囲の大きなプロジェクトでは後者のフォーマットが使われることが多い気がします。私の書く Design Docs は高々隣接するチーム内での合意形成なので、前者のような暗黙的なやり方で進めることが多いです。
アーティファクト
人事評価や後年のソフトウェア考古学のための史料として残します。コードを読めば現在の挙動は分かりますがそこから問題の背景や全体像を理解するのは難しく、その苦労をショートカットする上でこういったドキュメントが役立ちます。何も覚えていない半年後の自分への手紙みたいなものです。よくあるのが「君が作ったコレを拡張したいんだけど、リファレンスやコードロケーションを教えて」ということを一年後に言われるパターンですね。Design Docs がないと、自分で一からコードを読んで説明することになります。またプロジェクトを推進したという成果は定量的な評価が難しいですが、その痕跡を Design Docs にまとめることで評価対象者がどのように議論をドライブしていたのかを後から客観的に検証することができます。このように Design Docs は自分のためのお守りにもなります。
===
どうやら私は設計書的な用途と議事録的な用途をごっちゃにして Design Docs を書いているようです。この辺りは @sawawww さんが指摘されていてなるほどと思いました。
design doc なるものは、「設計書」と認識するか「議事録」と認識するかで判断が変わるものだと理解している。
— Yuta SAWA (@sawawww) March 26, 2021
僕は最近は議事録としてしか認識してないが、世の中では「設計書」もしくは「仕様書」と認識している人が多いことも理解している。
設計詳細を含むか?
「設計詳細を Design Docs に含めるか?」が私のタイムライン上での論点の一つになっていました。「background, motivation, security / privacy concerns, alternatives considered 辺りしかちゃんと見ない」「設計詳細は実装の進行によって陳腐化しやすい」「コードを読む方が分かりやすい」などが設計詳細を重視しない点として挙げられていました。私も概ね賛成である一方、この辺りは 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 はどういう時に書くべきでしょうか。
私の感覚では、1-3 パッチ程度で完結する作業であれば Design Docs はいらないと思います。コードの変更や commit description で文脈を完結できるからです。一方、複数パッチで数週間にまたがる変更、特にアーキテクチャ上の変更を伴う場合はコードレビューだけではパッチ外の意図やエンドステートを理解するのが難しくなるため、Design Docs が必要になってくると思います。特にレビュワーの立場だといきなり大作パッチを見せられても有意義なコメントをしづらいので「まずは Design Doc を見せてくれ。なければ書いてくれ」とお願いすることもあります。あと選択肢が複数あった場合には Design Docs が欲しくなります。いわゆる alternatives considered セクションですね。
要するにパッチからは伺い知れない文脈がある場合は Design Docs が欲しいです。
おわりに
本記事では私の持つ Design Docs 観についてあれこれ書きました。考えを整理する中で、私は自分のために Design Docs を書いていることが多いことに気づきました。そのためか Design Docs に対して悪い印象は持っていません。一方で読み手に対する配慮が欠けがちであることにも気づきました。今後はもう少し読み手に優しい書き方を心がけていきたいですね。
Design Doc を書くのはしんどいけど、合意取ってあとはそれに従って手を動かすだけのフェーズに突入するとプログラミングに没頭できて楽しい。合意を取るまでのフェーズを「種まき」、ひたすら実装するフェーズを「収穫期」と個人的に呼んでます。
— nhiroki (@nhiroki_) November 26, 2019