うさぎ組

ソフトウェア開発、チームによる製品開発、アジャイル、ソフトウェアテスト

設計書論争での独り言

重要な事

これは僕の経験に基づくものであり、世の一般的な皆々様にはあてはまるかどうかは存じ上げません。
僕がマイノリティかマジョリティかどうかはよくって、こういう状況もあるというだけです。ツッコミは大歓迎ですが「それはコーナーケース過ぎる」というご意見には「そうかもしれませんね。」としか答えようがありません。
あと、基本的に@に向けた記事なので、言葉足りていない部分が多いと思いますが、彼とは職場が一緒でいろいろ共有できるので気にしていません。皆さんには言葉足りていなくってすいません。という謝りはすれども、反省はしない程度の感じ。

追記>>
言いたい事書いてなかった。
ただし、
設計書否定するなら、ここにある事くらい論破するくらいの人じゃないと一緒に仕事したくない。逆に、ここに同意するくらいなら設計書否定すんなよ。自分の仕事を呪え。
と思ってる。
<<追記


ではちょいちょいカテゴリ分けして書いていきます。

プログラミング言語が十分に読み易くなった現代では不要という主張

あくまで経験上の感覚だけど、プログラミング言語ソースコードを読むのと、自然言語のドキュメントを読むのにはかかる時間が圧倒的に異なる。僕のスキルだと10:1くらいの差がある。つまり、僕はコードを読み書きするのがものすごく遅いと言い換えてもいい。
なので、結局UMLみたいな図を書きながらコードを読む。
そして思う。「最初から図を用意しておいてほしいな」と。
そこの効率を無視したほうがよい場合ってようは仮の値としての10倍以上の時間をかけても効率がいい場合ですよね。別に比はいくらでもいいけど、その効率を考えて言っているんだろうか。プロジェクトに関わる人が8人いたら、8倍だし。
もちろんそれをサポートできる充分なDSLを用意できているなら別だと思うけど、DSLで記述できている層とこまかいロジックを書く層が綺麗にわけられている(他にもたくさんあるけど一例としてこんなこと)とか、僕が接してきたプロジェクトではあまりみかけていない。
逆に、自然言語だと1/10の時間で見渡せるので、同じくらい品質がわるくても、その分たくさんレビューができる。
問題は形式的検証ができないところ。でも、そのソフトウェアがどのようなものであるかを理解するために必要なものだと思う。
僕は静的型付け関数型言語も好きだし、他のスキルセットと合わせてどんどん得意になりたいと思うけど、そういった言語によって表現できる「人間が一度に認識出来る視野当たりの情報量」というのはまだまだ少ないと思う。
僕ももっと形式言語で表したいけど、現状ではそれはまだできていなくって悔しい思いをしている。ってかんじ。


基本設計書と詳細設計書の違いについて

それぞれの名前はどうあれ、二つにわけられていることが多いですね。どうだっていいんですけど。
「つくるべきものの意図が十分に伝わっていない設計書にいかほどの価値があるのか?(意図が伝わる設計書にすべきである)」ということが焦点なのです。
具体的な一例(あくまで一例)は「それがどう動く事を保証したくて、どう動かない事を保証したいか」がそれぞれにおいて境界が明示的になっていることです。
僕の見てきたなかだと、
基本設計書 -> これからつくりたいものを外部IFベースで記述
詳細設計書 -> どうつくられているか(もしくはつくるべきか)を記述
ってことが多かった。
境界が明示的になっていない設計書や仕様書からソフトウェアをつくっているときには開発者の勘になります。ここで詳細な何かのMTGをするということによって「検討すべきだったこと」か「やらなければわからなかったこと」だったかはわかるでしょう。
YAGNIが呪いだとか、事前設計が呪いだとかいう話をしているのではありません。
ここで、迷ったということは当時の設計書では意図が伝わっていないということです。つまり、設計書に反映させるべきなのではないでしょうか?そして、これはテストではよくあることです。テストを設計すると多くの項目が抜けている事があります。私は幸か不幸か、テストに充分な基本/詳細設計書というのを見た事がありません。
コードを見てもわかるのは「明らかなバグ(パラメータや設定のミスなどなど)」であり、「想定されるべき挙動との差分」はコードではなく「意図に込められます」。前項と被りますが、僕が見てきたコードには「こう動くべきロジック」と十分に表現されたものはありませんでした。(なんかこの辺の話はuskzさんが大阪の関数型勉強会でしていたような。)
ちょっと例えると「普通にありそうなものをつくる」というのは非常に複雑なコンテキストのうえに成立している事をいろんな場面で経験しているはずなのに忘れられがちな気がしています。(普通の幸せな家庭をつくるとかもそうだよね。どんなモデルだよ!っていう。いろんな家庭ルールあるじゃんね。
僕は設計書が事前につくられるべきとか事後につくられるべきとかは思っていません。それはチームの開発体制によって大きく異なるからです。


明確な境界のないテストや実装には破壊がない

コードのみを見ても明らかなバグを発見できるだけで、ソフトウェアが正しい事を確認するためにはなんらかの意図が必要であることは前項でもふれました。(これはどの段階でも言える。設計でも実装でもテストでもユーザー受けいれでも)
意図のない状況で行うテストや実装はある意識がなければ「自身が行おうとすることを確認する/信頼した行為」になりがちです。
TDDの原則で触れられている「不安」というのはこの「自身が行おうとしていることの確認」です。
でも、「慎重に正しそうであることを確認すること」と「間違いがないことを確認すること」は全く違います。
あまり比喩はよくないかもしれませんが、僕はこれを小説とか漫画とか試験に例えます。作者と編集者/レビュアーの関係であったり、なにかの試験の生徒と先生。どちらも完成を目指しているけど、あきらかにみてる視野の広さが違う。
ソフトウェアに話を戻すと、意図とのズレがバグであり、意図がないとズレが何かを認識出来ないので、バグを見つけるべき方向性が立たない事になります。
ソフトウェアがある人にとって正しそうであることすら確認できないのに、そのソフトウェアは何が完了したと言えるのであろうか。。。


まとめ

ほかにも書きたい事があるんですけど、ちょっと収集つかない(文章力がない)のでこのへんで。言葉不足感満載でごめんなさい。

  • これはあくまで僕の経験であり、@への返事である
  • 設計書は意図を表現すべきだと思う
  • 意図の具体例としては境界がある
  • 境界は往々にして詳細設計書にあるが、それがないことは意図を表現しきれていないことになる
  • テストや実装には信頼と破壊があり、正しいことを確認するには両方必要であるが、破壊には意図が必須である

どこに書くか迷った事としては、意図がないときにコードから意図を読み取る必要があって、「なんでリバースエンジニアリングと要件定義一緒にやってんの。。。」っていう状態になります。そういうのやめたいです。


最後になったけど、形式言語で境界を綺麗に表現できることは往々にしてあるし、Alloyなんかで検査とかできるし、Coqとか使って幸せになれると思うので、どんどんそっちに傾倒したい。でも、現状では自然言語や図形での表現力の代替にはなっていない。僕が触れるプロジェクトでは両手あげて自然言語や図式の代替と出来るほどあまくはない。といったところです。
このまえSmalltalkが文字列で図形?(矢印とか箱とか)を書いて見やすいDSLを構築していると聞いて胸がアツくなりました。そういった方向にもっとアンテナはりたいですね。