僕は Design Doc に対して、あまり感情を持ってない。「Design Doc は最高です!」みたいな話を聞くと鼻白むものもあるけど、有用なケースもあると思う。ただ好悪は置いておいて、めんどくさいから書きたくない。実際のところ、ほぼ書いたことがない。
よりよい未来のため
Design Doc は未来の失敗を回避するために有用なのはわかる。特にグーグルのサーバサイドの文化という気がするんだよなあ。グーグルは共有のインフラがすごく多くて、共有のライブラリもものすごく多くて、全てを把握してから開発に入るのは不可能。ひょっとしたら同じものあるかも、と思いつつも Design を書いたら、それは XX でできるよ、ということはありそう。
あと、グーグルの Design Doc のテンプレートには privacy concerns や security concerns という項目があって、こういうのはプロダクトのデザインをひっくり返す可能性がある割に専門家が少なく、前もって相談しておくのは有用だろう。それと最初の方の Background とか Motivation も地味に重要な項目だと思っていて、「それってそもそもやる意味ある?」と実装してからなってしまうのを防ぐ効果もあるように思う。単に自分が解きたいから、解けるから、という理由で存在しない問題に取り組んでしまう人というのが、一定数存在すると思っている。(これはかなりブーメランである)
というわけで、自分より特定領域を知ってる人がいる時に相談する手段としては、まあ割と良いのではないでしょうか。知らんけど……
過去を自分語りする楽しさと、有益さ
設計と言ってもハイレベルから細かいとこまで色々で、ハイレベルなところでは割と有用なんじゃないかな、というのが前段で言いたかったことかもしれない。例えば使うコンポーネント選択とか RPC の流れレベルのハイレベルな決定には有用そうな気がする。 それより細かい話になってくると、 morita さんの「不確実性の軽視」や karino さんの「Design力が過大評価」の話になると思うんだけど、正直実装を書いてるうちにそのレベルの設計はガンガン変わってくるよね、となる気がする。 どうせ実装やってる間に細かい設計はガンガン変わっていくのだから……という意味で、 kzys さんの「デザインの前にプロトタイプ作ります」とかすごく僕は好みの考え方。ホントそれでいいと思うなあ。やってみてわかることってやっぱり多いと思うし。前段で批判した「存在しない問題を解いたけど誰も困ってなかったらから誰も幸せにならなかった」的な状況でさえ、何もしてないよりは成長が得られるだろうし。その様子をハタで見てると「それ事前に相談しておいてくれればもう少し筋の良い提案ができたのに……」となることもあるだろうけど。
グーグルでは一応 Design Doc を現状の design と一致するように更新することが推奨されていた……と思ってたけど、 morita さんがそう言っていないので、あまり自信はない。いずれにせよ多くの Design Doc は実装以降アップデートされてないので、 morita さんの「「古くなってるけどだいたい合ってるよね」という感じで読まれる想定がある」はそのとおりだったと思うし、そこらへんに読むのですらだるくなってしまう理由があるのだと思う。「なんで後で間違ってると判明したかもしれない設計を熱心に読まないとダメなんだ?」ってなりそう。 そんな理由で、細かめの設計は、なんかむしろ事前に書くより後で書くのがよいのかもしれないな、と思った。 morita さんの言及していた ARCHITECTURE.md のように。事前に書くより実際のコードの設計と一致してる可能性が高いので後から参照された時の有用性も高そうだし。僕は割と自分語りが好きというか、ドヤりたい性分なので、そういうのは割と書いたりする。
僕の好みのスタイルと、 kati の例と
というわけで、事前段階ではモチベーションの確認、他プロジェクトとの関連性、大枠のデザインに激しく影響する部分だけ必要なら Design Doc なりなんなりで議論して、さっさと実装して、うまくいったら ARCHITECTURE.md を書いてドヤる、というのが僕としては好みなのかな、と思った。ところで、この文章も特に考えをまとめてから書いてないので、この章を書き始めたあたりで、「僕は考えをまとめながら進めるのが好きなのだなあ」と自分の嗜好を自覚した状態。
これを書く前の事前の相談で kati とか Design Doc とかどうしたの?と聞いてもらったのだけど、ちょうどそういう、あまり事前に相談せず後で説明を書くスタイルだった気がするので書いてみる。
kati というのは数年前に書いた、 GNU make の Android のための中途半端な別実装。 make がクッソ遅いというあからさまな問題があり、 motivation は明快だった。 drop-in-replacement を指向していたので、関連プロジェクトもない。というわけで Design Doc とかは一切書いてない。その前のプロジェクトの都合もあり、 Android.mk という GNU make の上で構築されたビルドシステムが何をしてるからはだいたいわかっていたので、なにかをキャッシュすれば速くなる、とは思っていたと思う。
それ以上のことは何も設計してないし、まさに「デザインの前にプロトタイプ作ります、うまいこといったらそのまま本番ということで」スタイルの進行だった。 GNU make 、ユーザとしてはある程度知ってるつもりだったし、一緒にやっていた ukai さんも僕も簡単な言語処理系くらいならサックリ書けるでしょ、くらいの自信はあった。でも、実装を書いてみると知らないことがたくさんあり、 ukai さんと二人で理解を深める手段として実装を書いていったような感じだったと思う。普通に考えてこういう処理してるでしょ、みたいな予想を GNU make が次々と外してくるので、激しくお互いのコードを書き直しまくってたいたように思う。関係ないけど、思い出すにこれも含めて ukai さんとの作業は楽しかったなあ。また機会があれば、と思う。
「なにかをキャッシュする」ことにより劇的に速くなる予定だったので、たぶん Go でいいでしょ、と書いていて、そのまま本番で使うつもりで実装をしていた(ukai さんが Go ファンなので、リクルートする口実になるという事情もあった)。だけど、そのうちに、これでは速度的に気に入らないなあ、と C++ で書き直したので、事後的に最初に書いていた実装はプロトタイプだった、ということになった。 C++ の再実装も、 Go の経験があるぶんやり直しは少なかったけど、後になって判明した必要な機能で全体をいじったり、高速化のためのアレコレを入れたり、割と最後の方で make の drop-in-replacement という方針を放棄して ninja を生成する方針に切り替えたせいで設計が少し変わったり、割と有機的に変化を続けていた。
このへんは Design Doc で事前相談してたら防げていた出戻りだったんだろうか。そんな気がする部分もあるけど、深く考えず実装を進めていったからこそ気付いた問題もある気がしている。このいきあたりばったりとしか言いようがないワチャワチャやってる時に、信頼してるのかダメ元なのか、とにもかくにも猶予をくれていた当時のマネージャの懐の広さには感謝している。僕なら止めるし、僕はマネージャの類になってはならない、と思う所以でもある。
こんな感じでやけに長く経緯を書くことから分かる通り、僕は自分がうまくやったことを語りたいタイプであり、自分が面白い、ここは変だ、工夫した、頑張った、など書くのは楽しく、ポエムを書いた。日本語だとこれ で英語だとこれ 。これは割と ARCHITECTURE.md 的な役割を果たしたのかもしれない。 kati はその後 US の人がメンテしていてくれて、ごくまれにグーグル外の人も話題にしてくれているのを見るのだけど、ここに書いたようなことはわかっている前提で会話していてくれるような気がしていて、ひょっとしたら書いた意味があったのかなあ、などと思っている。まあでもおおむね自己満足という意味合いが強い気がする。
逆に失敗談も書いておくと、 kati の直後にやった Dependency Sanitizer というやつは、プロトタイプもよく動いていたし、 名前もかっこいいし、自分が書いたドキュメントでは最も Design Doc に近い体裁だったと思っているんだけど、びっくりするほど全く人の興味を得られず、悲しい感じで立ち消えていってしまった。今でも良いコンセプトだったと思ってるので、何が悪かったんだろうなあ……と時々思い返している。