2007-09-24

設計文書のうまい書き方

訳して YukiWiki に置きました. 元は "How to Write an Effective Design Document".

友達が "最近, プロジェクトで設計仕様書を作ろうって話が..." と悩んでいた. そりゃ大変だねえと相槌をうち, 相槌ついでにぐぐっていたらみつけた記事. <design document><designdoc> と検索すれば ガイドラインだけでなく実物もじゃんじゃかみつかる. 玉石混交で面白い.

設計仕様書と聞くと, 設計する人と実装する人が異るような大規模開発をまず連想する. そっちの世界で文書が必要なのはわかるが, 一方で私は大規模開発をしたいと思わないし, 興味も湧かない.

元の記事も私の友達もそんな大規模開発を想定していない. 文書化した本人が実装も行う. それでもこの記事からは (訳しておいてなんだけれど) いまいち違和感が拭えない. 私はもともと反文書化, 反コメントのコード原理主義者なので, 文書化の話が全般に気に食わないという面はある. そんな好みは保留しつつ違和感の出所を考えてみるといくつかの疑問にたどりつく. 疑問: そもそも設計するの? 設計を他人と議論するの? その文書は有益な議論に繋がるの?

そもそも設計するの?

私は長いこと設計仕様と呼べるものを書いていない. 理由の一つはそもそも設計をしていないからだと気付いた.

私はスパーハカーだからコードは書いた端から完璧に動く, というわけではない. (そりゃね...) 設計のいらない仕事, 設計の解空間が狭い仕事は結構ある. 既存のフレームワークに乗ってコードを書くなら, フレームワークの出来が良いほど設計の余地は少いだろう. やりたいことをルールに従って符号化すればいい.

書きかけコードの穴埋めはその亜種と言える. おおまかなフローや構造はエースが書き, 細かな機能追加やバグとり, 移植などを手分けして済ませることは多い.

このように枠組みの穴埋めをする仕事は設計の余地が少い. "上流工程" に相当する部分をフレームワークが済ませていると考えれば納得がいく.

設計を他人と議論するの?

フレームワークの外側で仕事をすることもあるけれど, やはり文書化はしなかった. プロジェクトのプログラマが自分一人だったからだ. 議論する相手がいなければ文書を書いても仕方ない.

メンテナンスや引き継ぎのために文書を書けという向きもあるが, これは私の好みを差し引いてもうまくいかない事が多いだろう. 引き継ぎ文書は書き手の旨味が薄く, 従って動機づけが弱い. 引き継ぎ文書がなくても書き手は大して困らない. (読み手は困るだろうけどね.) 文書がないことで書き手が困る場面はいくつか想像できるけれど, それが文書作成の手間に見合うのかは疑わしい.

件の記事も書き手の利点を強調している. 設計時の問題発見やリスクの移譲はどちらも書き手に利点がある.

その文書は有益な議論に繋がるの?

これまでに挙げた二つの疑問は私個人の経緯による部分も大きい.

そこでフレームワークに頼らず, 広い問題空間をチームの仲間と切り開いていく, そんなステキプロジェクトで仕事をしているとしよう. 設計上の検討に漏れはないだろうか? モジュール間のシーケンスに勘違いは無いだろうか? 同僚と相談することは多い.

で, 設計文書を書いたとする. そのレビューをどうやって同僚に頼めばいいだろう? 同僚が書いた設計文書のレビューを頼まれたとする. 何を検証すればいいだろう? 先の記事はそうした視点を欠いている. 私も設計文書を書いたことはあるけれど, そこから有用なフィードバックを得た記憶はない. 逆に他人の設計をレビューしたこともあって, やはり良いレビュアではなかったと思う. (議論を自転車小屋化しがちだった. 反省...)

マネージャにリスクや懸念を移譲するケースにも同じことが言える. マネージャに懸念が伝わったとどう確認すればいいだろう? 仕様が曖昧で困る, 顧客に確認して欲しいと頼んだはずが忘れ去られることはよくある. 無理と伝えた機能を後からやっぱり入れろと迫られることもある.

車の両輪

良い文書を書くための "読者を意識する" という指針がある. これは十分でない. たとえば同僚のプログラマを読者と識別したところで, その読者を楽しませるステキアルゴリズムの紹介を書いても仕方ない. 設計文書の目的が早期のバグ発見だとしたら, むしろステキでない面倒な部分を扱うべきだろう. "良い文書を書く" という文書中心の視点は主題を見誤りがちだ.

ソフトウェア開発における文書には, いつも対となる作業がある. たとえばレビュー. どのようなレビューを行うのかをはっきりしないと, どんな文書を書けばいいかはわからない. 結局はコードを書いてテストするまで問題はわからないのかもしれない. あるいはリスク管理や責務移譲. 伝えた懸念をマネージャがなんとかしてくれる確信が持てないと, 文書にまとめる意欲は湧かない. 口頭やメールやチケットで何度もせっつく方が手堅いかもしれない.

なにより設計そのものがそれほど自明な作業ではない. 作業の進め方や成果が曖昧なまま文書を書いたなら, 冴えない結果になるのは当たり前だ. 文書より設計そのものが重要であることは件の記事でも念を押している.

協調的コンストラクションへ

文書が対話や協調の手段であるという基本的な事実に立ち戻ろう. レビュー, インスペクション, ブレインストーミングといった ソフトウェア開発における対話と協調の役割を, CODE COMPLETE では "コラボレーティブ(協調的)コンストラクション" と呼んでいる.

最も形式的で強力な協調のやりかたであるインスペクションは文書を求める. もし設計のインスペクションを行うなら, その入力として書く設計文書には意味があるだろう. ソースコード以外のインスペクションをどうやるのか私には見当がつかないけれど, インスペクションの要件を満たす文書はそのプラクティスから逆算して定まるはずだ. レビューやインスペクションは開発の早い段階でやった方が良いと言われている. 設計時のインスペクションは, それが可能なら望ましいプロセスだと言える.

設計時のより非公式な協調には, たとえば以下のようなものがある. CODE COMPLETE の 5 章より引用:

引用ここまで.

この中で設計全体を文書化する必要がありそうなのはウォークスルーくらいだ. ウォークスルーも口頭での補足ができるから, 文書は自己完結しなくていいかもしれない. その他も必要になる文書はみなアドホックで, 部分的で, 揮発性がある. これはコミュニケーションの性質そのものだと思う. この身軽さを損う文書を私は好まない.

コードで行き詰まって設計をしておけばよかったと思ったとき, ひどい設計の失敗をした後輩の後始末をしているとき, その反省から設計文書の雛形を作るのは, まして私にそれを押しつけるのは少し待ってほしい. 足りないのは設計自身かもしれない. でもコードの手前で思いとどまるのにいつも文書はいらない. 足りないのは目玉の数かもしれない. でも他人の助力を得るのにいつも文書はいらない. 設計のアイデアを吟味しよう. 協調の手札を試そう. 共有フォルダの肥やしを増やすよりは役にたつよ. きっと.

関連がなくもない記事