ソフトウェアの開発に限らず、ものを作るには「設計」という行為が不可欠です。多くの人は、中学生の時の授業で椅子などを作った経験を持っていると思います。その時、「設計図」らしきものを書いて、形や強さを検討したり、どれだけの材料が必要か、どのような道具が必要か、さらにどのような技術が必要かといったことを見極めたことでしょう。
もちろん中には、設計図を書かずに、イメージに任せて適当に材料を切っていったという人もいるでしょうが、作り慣れない人には、それは難しいでしょう。しかも、ある程度組み上がったところで、強度の不足に気づいて補強しようにも場所的に金槌が巧く使えない状態になっていたり、材料を計画的に切り出さなかったために、途中で材料が足りなくなったりしませんでしたか?。
ソフトウェアの世界もこれと同じで、やはり設計という行為が必要なのです。ソフトウェアに於ては、一般に、求められている機能を実現する方法はいくつもあります。椅子の工作と違って、何倍もの方法があるのです。その内のどれを選ぶかは、実現の容易さなど機能以外の要求の影響を受けるのです。決して「機能」だけで決まるのではありません。性能やパフォーマンス、操作性、保守性、移植性、効率など、機能以外にもいろんな要求があります。特に、機能以外の要求は、「設計」という行為を経ないかぎり、うまく“組み込む”ことは出来ないのです。
K/Bからソースを打ち込みながら、これらの非機能的要求を実現することはほとんど不可能です。その理由は、これらの非機能的要求は、特定の関数やクラスのメッドで実現されるものではないのと、対機能的要求も含めて、要求自体が互いに矛盾する可能性があり調整が必要だからです。どこかで“折り合い”を付けなければいけないのです。椅子の工作の時のように、後になって、これらの非機能的要求を満たしていないことに気づいても、簡単に直せない可能性があるということです。いや、イスと違って、ソフトの構造的欠陥は、外見から知ることができないので、もっと厄介です。
例えば性能やパフォーマンスは、データ構造の影響を受けることがしばしばあります。そしてデータ構造の変更は、システムのアーキテクチャの変更につながってしまうもので、大抵の場合、システムの大改造となります。操作性でも、データ構造の影響を受けることもあるのです。保守性や移植性などは、関数やクラスの構造の影響をまともに受けますし、それ自体もデータ構造によって影響を変わってきます。それも「群」単位の構造に影響されますので、実際問題として、後からちょっとした手直しで実現できることはほとんど無いと言ってもいいぐらいです。kのことは、「設計」という行為に置いて、データ構造が重要な意味を持っていることを示しています。
設計書は詳細機能の羅列に終始
ほとんどのソフトウェア・エンジニアは、設計という行為(工程)の存在(や必要性)は認識しています。いや、それをちゃんとやっていると言うかも知れません。確かに、「設計書」と名のつくドキュメントは、意外と書かれているのです。しかしながら問題はその中身です。中身が「設計書」になっていないのです。
いちばん多く眼にするのは、そこで実現すべき機能の詳細な記述になっていることです。エラー処理も含めて、そこで分担している機能(仕様)が細かく書かれているのです。たしかに、要求をソースに変換する前には、詳細な仕様が把握されていなければ実現しません。そこで使用するROMデータの(テーブル)構造も書かれています。これも別の人が作ってくれるので、はっきりしています。
でも、自分が「設計」行為の中で作りだすデータの構造は書かれていませんし、自分が管理するバッファの使い方も書かれていません。個々の関数やクラスに於て、どのような処理を分担させながら要求を実現しようとしているのかも書かれていません。機能の実現以外に、どのようなことを優先したのかも示されていません。実は「設計書」として見たいのはまさにこの部分なのです。そこでどの様な機能が実現されようとしているのかということではなく、非機能的要求も含めて、それらの詳細な機能(仕様)をどのように(How)実現しようとしているのかを知りたいのです。
関数の集大成のケースも
もう一つのパターンは、個々の関数の仕様(入力、出力、処理の概要など)の集大成になっているものです。これでは、“このような関数たちで出来上がっています”ということを示しているだけであって、どうやって実現しているのかとい「設計の意図」を知ることは出来ません。もっとも、オブジェクト指向では、関数の集大成は姿を消すでしょうが、かわりにクラスの集大成あたりが出てくるのか、それともこの機会に何も書かれないかでしょう。「C」以上にソース自体にドキュメント性があることは確かですが、それも、クラスの設計次第ですし、ソースの書き方次第です。省こうと思えばいくらでも省けます。逆に、省かれたら、「C」以上に読みにくいソースになる危険もあります。
一般にこの設計書のパターンは、後から作った場合に多く見られます。全部終わってから、今更「設計の意図」なんて書けますか。第一、思い出せやしません。いや、意地悪く言えば、最初から「設計の意図」なんて無かったのですから、書くことは無いのです。結局、目の前にあるソースを“変形”させることしか出来ないわけです。
関数のI/F仕様が不要だというわけではありません。他の人に使用を公開しているような関数については、その仕様が定義されている必要はあります。しかも「先出し」で必要です。でも、特殊な「共通関数群」でも担当しないかぎり、そんなのは分担の中の1割もないでしょう。
もちろん、ソースの制作を全て外部に委託するような場合は、関数や個々のクラス、さらにその中のメソッドまで、詳細に記述されることになりますが、この場合は、関数内部のアルゴリズムまで具体的に書かれるはずです。第一、それは“後付け”の設計書ではありません。
ここでいう意味のない設計書は、ほとんどが“後付け”で書かれるのです。すでにソースも書き終わり、すったもんだのテストもなんとか通っているのです。そこから書く“設計書”にいったいどんな意味があるというのでしょう。
設計書の役割
なぜ、設計書が必要かというと、一つは、そのままソースの制作に着手してよいかどうかの判断に使いたいのと、もう一つは、メンテナンスの時のよりどころとしたいのです。
実現されるべき機能や品質が、“うまく”盛り込まれているかどうかは、制作者以外の人を交えて検証(レビュー)しなければなりません。椅子の工作のようなものなら、そこまでやらなくても良いでしょうが、ソフトウェアの製品ともなれば、簡単には行きません。それに、顧客からの要求は製品のレベルに対して出ているのであって、各担当者の分担のレベルで出されているわけではありません。アーキテクチャの設計のところで、それぞれの担当者への持ち分に応じた機能に形を変えていますので、担当者には、必ずしも元の要求とつながって理解されているとは限りません。従って、ちょっとした勘違いがあっても、自分では気づかないでしょう。
事前のレビューが必要なもう一つの理由は、間違いを後(テスト工程以降)で見つけるよりも、事前に見つける方がはるかにコストも時間もかからないからです。そして何よりも、この事前の検証によって、その部分がどのように設計されているかを、制作者以外にも知らせることができるということです。これがテスト工程に入っての変更制御に大きな威力を発揮するのです。
さらにメリットがあります。それはいざとなったら、ソースの制作に人手を投入できることです。一般に、途中からの人の要員の投入は、かえってスケジュールを遅らせたり混乱させるものですが、それは、適切な中間の成果物が作られていないからです。中間成果物の存在、あるいはその内容によっては、この段階に入っての応援も可能になります。もちろん、応援部隊にもそれなりのスキルが条件にはなりますし、全ての工程に通用するわけではありません。
一方、設計書がメンテナンス作業に与える効用にも大きなものがあります。どのような意図で、そのような呼び出し構造、あるいはクラスパターンになっているのかが分からないままに、ソースに手を加えることはとても危険なことで、それは今更言うまでもないでしょう。そのことで、これまで何度修正ミスをしてきたか。何度、不適切な修正をしてきたか。ソースに設計者の意図を表現するには限界があります。所詮、全体を表現したり、その中の部分であることやそれぞれの関係を“一見して”分からせることには向いていません。ソースは所詮ソースであり、機械が扱いやすいように構成されたものなのです。“ソースに書いてあるから”というのは、多くのの場合、制作者の独りよがりです。
設計者はここで何を考えてこのような呼び出し構造、あるいはクラスパターンを選んだのか、と思って「設計書」を開いたとき、そこに展開するのが機能の詳細な記述だとしたらどうでしょう。どのページをめくっても、単なる関数のI/Fしか書かれていないとしたらどうしますか。そんなものは、それこそソースを見れば分かるし、事前にソースから抜き出すことだって簡単にできるのです。
確かに機能の詳細な記述(仕様)は必要なものです。でも、それだけで設計書になるわけではありません。ソフトウェアの詳細仕様として、設計書の前半分を使っても構わないし、レビューの関係で別冊にまとめても構いません。でも設計書には、やはり「どのように Design したか」を書いて欲しいのです。
設計するということ(2000/5/21 追加)
それでは「Design」するということは、何を「Design」することなのでしょう。問題はここにあるわけです。「椅子」を設計するときも、実は、構造を設計しているわけですが、ソフトウェアの場合は、第1に「データ構想」を設計することになります。3人座れるような椅子にするには、どのような構造にすればよいかを考えるように、そこで求められている機能的要求や品質的要求(いずれも“仕様”のレベルであること)を満たすためには、どのようなデータ構造にすればよいかを考えるわけです。データ構造が決まれば、処理の構造も決まってきます。少なくとも処理の構造は絞り込めるし、今度は、「複雑度」などの「モジュールの尺度」を使って、処理の構造を「Design」します。
従って、「Design」で重要なのは「データ構造」なのです。そこで求められている機能や品質に関する仕様を満たすのに、どのようなデータ構造がふさわしいかを考えるのです。データ構造によっては、求められている機能や品質の仕様を満たせないことも起きてきます。
もっとも、このような「データ構造」の知識を持っていても、「Design」の結果に差が生じることがありますが、それはそこに求められている要求(仕様)に対する「優先度」の判断が違っていれば、採用するデータ構造にも違いが生じてしまいます。もちろん、データ構造の知識を欠いていれば、結果は全く違ったものになることは容易に想像できることです。
データ構造とは(2000/5/21 追加)
それでは、「データ構造」とはどういうものか。基本的なデータ構造は、それほど多くはありませんので、以下に列記します。
配列(テーブルと呼ぶことがある)
リスト(リングバッファはここに含まれる)
待ち行列(一般にキューと呼ぶ)
スタック
木構造
また、データ構造に伴って「探査アルゴリズム」というのがあります。
2分探査
ハッシュ方
などがあり、
さらにソートやマージなどのアルゴリズムは、探査法を支援するために必要になってきます。
もし、こういったデータ構造や探査法の知識がないのなら、急いで適当な文献を入手して研究してください。これが無ければ前に進みません。
次の役割は?
このように、設計書が書けないソフトウェア・エンジニアの仕事の精度というものは、おおかた予想がつきます。機能の盛り込みが漏れていたり、実現の仕方に深い考えがないために、機能の実現に“すき間”があるものです。第一、品質的な配慮はほとんどなされていませんので、性能などの評価ですぐに欠陥が指摘されます。そうしてバグを修正したら他のところがおかしくなったり、必要以上に呼び出しの深さが深くなって、スタックの領域を多く食ってしまったり、良いことはほとんど無いのです。
設計書を省いた分だけ、完成が早くなったかというと、ほとんどの場合、決して早くならないのです。規模や状況によっては逆に遅くなるといってもいいでしょう。確かに最初は調子よくソースを書き始めるのですが、作業が進むにつれてペースが落ちてきます。関数やクラスの関係などを確認するために何度もソースを読み返す作業が増えてくるのと、一度書いたものを何度も手直しするということになるからです。設計書なら、その部分は数ページに収まるものが、ソースですから画面を何度もスクロールすることになります。このとき、『理解度はページをめくる回数に反比例する』というデマルコの法則に完全にはまってしまうのですが、今更設計書は書けない以上、もはや対応方法は限られてしまいます。設計書が書かれていないために、第3者のレビューによる手助けも出来ません。結局、本人の両肩に全てがかかってくるのですが、こんな調子で、2ヶ月も、3ヶ月も作業の精度を維持しながら、納期のある作業がまともに出来るとは思えません。
それよりも、もっと心配なのは、彼はこの先どのような役割を担えるかということです。次の若い人たちの模範というわけには行かないでしょう(でも、やってきた?)。第一、教える「材料」がありません。経験を増やすために、彼に他の部分を担当してもらうにも、今の担当を外すわけには行きません。その分担は彼しか分からないのですから。じゃ、マネージャーが勤まるかというと、無理な相談なのです。意図して結果を導いたことのない人に、簡単にマネージメントは勤まらないはずです。その証拠に、多くの組織では必要なマネージメントが行われていないでしょう。
今、このページを読んでいる皆さんの中で、設計書といえるものを書いていないと言う人は、その構成や内容を、しっかりと研究して、急いで設計書が書けるようになってください。より良い設計ができるために、データ構造や、それに伴うアルゴリズムを研究してください。そうして「意図」して結果を出せるようになってください。「設計」も含めて、そこに明確なプロセスが存在していないのなら、あなた達が作ればいいじゃないですか。確かに、その組織は今日まで“その方法”でやって来たのかも知れませんが、そのままではこの先の市場(顧客)の要求に応えられないし、あなた達自身もボロボロになる危険があることが分かっているのですから、あなた達がやり方を変えればいいのです。あなた達自身で時代を変えれば良いのです。10年前と違って、適切な文献や有用な情報は容易に手に入るでしょうから。
あなた達が、その方向に動き出さなければ、何も変わらない可能性があるのです。