ソフトウェア設計とは何か?

(原文: What Is Software Design?

by

Jack W. Reeves
(c)C++ Journal - 1992



訳者まえがき

この文書は,Jack W. Reeves 氏が1992年に C++ Journal に寄稿した記事の邦訳です。 本記事では,オブジェクト指向プログラミング言語の代表として C++ を挙げていますが,これは本記事が執筆された当時,一般的に利用可能なオブジェクト指向言語は C++ だけであったという事情があるためです。 今では C++ に加えて Java,Delphi,C# といったオブジェクト指向言語が利用可能となっていますが,そんな今でさえこの記事は古さを感じないものとなっており,ソフトウェア開発の本質,現状を鋭くえぐるものとなっています。
邦訳の公開を許諾していただいた Jack W. Reeves 氏に,この場を借りて感謝いたします。

2003年1月27日 村上 雅章

補足

このページの文章タイトルは「ソフトウェア設計とは何か?」(What Is Software Design?)となっており,HTMLソースのタイトル(<head>内の<title>)は「ソフトウェア工学とは何か」(What is software engineering)となっています。 この経緯について読者の方から質問を受けまして,この度Jack Reeves氏より回答をいただきましたので,ここに補足としてあげておきます(宇野信太郎さま,ありがとうございます)。

タイトルが異なってしまった経緯(Jack Reeves氏の回答より抜粋)

  1. この論文は,元々「ソフトウェア工学とは何か」(What is Software Engineering)というタイトルで公開された。(その趣旨は,ソフトウェア開発とその他の工学分野間における有効な類似点を洗い出し,無効なものを切り捨てることで,ソフトウェア開発を如何にして真の工学分野に近づけていくのかを述べようとしたものであった。)
  2. その後,Ward Cunningham氏のWiki Webに,この論文について言及したThe Source Code is the Designというページができた。
  3. このため,Jack Reeves氏は原文へのリンクをその Wiki ページにポストしたが,その際,What is Software Designをリンク名とした。 そして,このリンク名が広く認知されるようになった。
以上(2003年5月16日追記)


オブジェクト指向技術,特にC++によってソフトウェア業界に嵐が巻き起こされました。 そして,この新技術の適用方法を解説した数多くの記事や書籍が出回るようになりました。 これにより,オブジェクト指向技術が単なるまやかしであるかどうかという疑問は,痛みを最小にして利益を得る方法についての疑問に取って代わることになったのです。 オブジェクト指向技術が,まだ世に出てからさほど時間の経っていない技術であることを考えた場合,このような爆発的普及は極めて異例であると言えるでしょう。 何故,オブジェクト指向技術は突如として人気を博するようになったのでしょうか? 様々な説明が行われました。 実際のところ,理由はたった1つだけではなかったはずです。 おそらくは,複数の要因が組み合わさって臨界点に到達し,人気を博することになったのでしょう。 とは言うものの,この最新のソフトウェア革命の中心にはC++自身の存在があったように思えるのです。 そして,その理由もたった1つではないのでしょうが,私は少し違った視点から答えを示唆したいと思っています: C++が普及したのは,これによってソフトウェアの設計とプログラムを同時に行うことが容易になったからなのです。

この意見が奇妙なものに感じられたのだとしたら,それは私の狙い通りです。 つまり,この記事で私がやろうとしていることは,プログラミングとソフトウェア設計の関係を考えてみるということなのです。 私はこの10年というもの,ソフトウェア設計として行われている作業とソフトウェア設計の真の姿というものの微妙な違いをソフトウェア業界全体が見逃してきたと感じていました。 私たちが気付くことさえできれば,C++人口の増加という現象には,私たちがより優れたソフトウェア・エンジニアになるために成しうる重大な教訓が潜んでいると考えているのです。 その教訓とは,プログラミングがソフトウェアの製造作業ではなく,ソフトウェアの設計作業であるということなのです。

何年も前の話ですが,私が出席したセミナーの場で,ソフトウェア開発は工学分野に属しているのかどうかという議論が行われました。 結論は憶えていませんが,その時の体験から,ソフトウェア業界は非常に有益ないくつかの類似点を見逃し,ハードウェア工学からの誤った類似点を創造してしまったという私自身の考え方が触発されたのです。 突き詰めると,私たちはソフトウェア設計というものの真の姿に気付いていないという点で,ソフトウェア・エンジニアではないという結論に達するのです。 そしてその思いは,今日さらに強まってきています。

工学としてのアクティビティの最終目標は,すべて何らかのドキュメントとなっています。 設計作業が完了すると,設計ドキュメントが製造チームに引き渡されます。 製造チームは,設計チームとは完全に違ったスキルを持った,まったく異なったグループです。 そして,設計ドキュメントが実際に完璧な設計となっている場合,製造チームは製品の製造を開始することができるのです。 つまり,設計者からの介入を一切受けることなく,その製品を大量生産できるようになるわけです。 私は自らが理解しているソフトウェア開発のライフサイクルを再吟味することにより,工学的な設計基準を本当に満足しているソフトウェア・ドキュメントというものが,ソースコード・リスティングだけであるという結論に到達したのです。

この仮定に対しては,賛否両論さまざまな意見が存在しているはずです。 このため本記事では,真のソフトウェア設計が最終的なソースコードであると仮定した場合に,この仮定から導き出される帰結のいくつかを検証しています。 この仮定の正当性を証明することはできないかもしれませんが,これによってC++が人気を博している理由等,ソフトウェア業界において見受けられるいくつかの事象について説明できることを願っています。

ソースコードがソフトウェア設計であると考えることによって重大な帰結が導き出されます。 この帰結はあまりにも重要かつ自明であるものの,ほとんどのソフトウェア組織において盲点となっているものです。 それは,ソフトウェアの製造(ビルド)が安価なものであるという事実です。 あまりにも安いため安価なものとして見なす必要すらなく,ほとんど無料といっても良いくらいなのです。 ソースコードがソフトウェア設計であると考えた場合,ソフトウェアの本当の製造はコンパイラとリンカによって行われることになるわけです。 私たち自身もソフトウェア・システム全体のコンパイルとリンクのプロセスを,しばしば「ビルドを行う("doing a build")」と呼んでいます。 また,ソフトウェア構築用の機器に対する資本投資も莫大なものとはなりません。 実際に必要なものは,コンピュータ,エディタ,コンパイラ,リンカだけなのです。 そして,いったんビルド環境が利用可能になれば,ソフトウェアの製造にはほんの少しの時間しか必要とならないのです。 50,000行のC++プログラムをコンパイルするには,かなりの時間が必要となるかもしれませんが,50,000行のC++と同じくらい複雑な設計のハードウェア・システムを製造することを考えた場合,取るに足らないものとなるはずです。

ソースコードがソフトウェア設計であると考えた場合,ソフトウェア設計は少なくとも機械的な意味合いにおいて,比較的容易に作成できるという帰結も導き出せます。 コードにして50行から100行の一般的なソフトウェア・モジュールを記述(すなわち設計)するには,たいていの場合,数日しかかかりません(完璧にデバッグを終えるということはまた別の話であり,それは後ほど考察しています)。 同程度の複雑さを有した設計を,ソフトウェア並みの期間で生み出せるような工学分野が他に存在するかどうか調べたいのは山々ですが,まず最初に行うべきことは,複雑さを測定し比較する方法を見つけ出すことでしょう。 ソフトウェア設計はむしろ迅速に肥大化していくというのが明らかなのですから。

ソフトウェア設計は比較的容易であるという点,そして製造は本質的に無料であるという点を考えた場合,ソフトウェア設計が信じられないほど巨大かつ複雑なものになりがちであるというのは当たり前のことなのです。 これは判りきったことのように思えるかもしれませんが,しばしば問題の規模が無視されているのです。 教育現場におけるプロジェクトでは,高々数千行のコードにしかならないことがしばしばあります。 しかし,ソフトウェア製品では設計者から引き渡された時点で10,000行の設計となっていることもあるのです。 簡単なソフトウェアで十分な利益が得られたのは,もはや過去の話です。 今や一般的なソフトウェア製品は,数十万行からなる設計となっているのです。 そして,百万行の大台にまで突入しているソフトウェア設計も数多くあります。 さらに,ソフトウェア設計はほとんど常に進化し続けるものなのです。 現在の設計ではコードにして数千行しかないかもしれませんが,その製品の一生を通じて見た場合,その何倍もの記述が行われることになるやもしれないのです。

ソフトウェア設計と同じくらい複雑なハードウェア設計が存在することは間違いありませんが,ここで近代的なハードウェアに関する2つの事実に注目しておく必要があります。 まず第1の事実は,複雑なハードウェア工学を適用した場合,ソフトウェアの批評家が私たちに信じさせてきたほど,常にバグのない状態が実現できていたわけではないというものです。 有名なマイクロプロセッサがロジックにエラーを抱えた状態で出荷され,橋は倒壊し,ダムは決壊し,航空機は墜落し,数千台の乗用車やその他の消費者向け製品がリコールされているのです。 これらは,すべて記憶に新しいことであり,すべては設計ミスの結果なのです。 そして第2の事実は,複雑なハードウェア設計にはそれに対応した複雑かつ高価な製造工程が用意されているというものです。 つまり,こういったシステムを作り上げる能力が必要となるため,真に複雑なハードウェア設計を作成できる企業の数自体が限られてくるのです。 しかし,ソフトウェアにはこういった制約が適用されません。 数百ものソフトウェア会社が存在し,数千もの非常に複雑なソフトウェア・システムが存在しているのです。 そして,その数と複雑さは,いずれも日に日に増大しています。 つまり,ハードウェア開発者の真似をしても,ソフトウェア産業の問題はそう簡単には解決できないということなのです。 それどころか,ハードウェア設計者はより複雑な設計を行うよう,CADシステムやCAMシステムを与えられ,ハードウェア工学はソフトウェア開発にどんどんと近づいてきているのです。

ソフトウェアの設計とは,複雑さを管理する作業です。 こういった複雑さは,ソフトウェア設計自身や,企業のソフトウェア組織,そして産業全体に内在しています。 またソフトウェア設計は,システム設計と非常に良く似ています。 つまり,複数に渡るテクノロジの橋渡しをしたり,しばしば行われているように複数の下位分野を含めることもできるわけです。 このため,ソフトウェア仕様は流動的なものとなりがちとなり,目まぐるしく変化し,設計プロセスの最中に変化することもしばしばあるのです。 また,ソフトウェア開発チームも,設計プロセスの半ばで変更されることがしばしばあるため,流動的なものとなりがちです。 ソフトウェアは,ハードウェアというよりも多くの点において,複雑な社会集団や有機システムに類似しているのです。 こういったことすべてがソフトウェア設計を難しい,誤りを生み出しやすいプロセスにしているわけです。 これは独創的な考え方ではありません。 しかし,ソフトウェア革命が起こって30年近く経った今でも,ソフトウェア開発は他の工学分野と比較すると規律のない技芸として見られているのです。

真のエンジニアが設計を完了させた場合,それがどれだけ複雑なものであっても期待通り動作するというのは,異論のないところでしょう。 そして,一般に受け入れられている製造技術を用いて製造できることも確実でしょう。 ハードウェア・エンジニアは,こういったことを実現するために,相応の時間をかけて設計の検証と洗練を行っているのです。 例えば橋の建設を考えてみましょう。 こういった設計を実際に建設する前に,エンジニアは構造解析を行います。 そしてコンピュータ・モデルを構築して,シミュレーションを行うのです。 また,縮小模型を作成し,風洞を使ったりその他の方法で試験を行うのです。 つまり,設計者は建設に先立って,その設計が優れた設計であるかどうかを確認する上で考えられることをすべて行うわけです。 新型航空機の設計ではさらに大変なことになります。 この場合,設計時の予測を検証するために実物大のプロトタイプを製造し,テスト飛行を行わなければならないのです。

多くの人々の目には,ソフトウェア設計がハードウェア設計ほど厳格に工学として実践されていないように映っているのは明らかです。 しかし,ソースコードが設計であると考えれば,実際にはソフトウェア設計者も自らの設計に対して相応の検証と洗練を行っていることが理解できるはずです。 ただ,ソフトウェア設計者はそれを工学と呼ばず,テスティングやデバッギングと呼んでいるだけなのです。 しかし多くの人々は,テスティングやデバッギングを本当の「工学」であるとは考えていません。 こういった状況はソフトウェア業界で顕著に現れています。 その理由は,工学との本質的な相違点にあるのではなく,コードが設計であるという点をソフトウェア業界が拒絶しているためです。 モックアップ,プロトタイプ,実験用見本は他の工学分野でも実際に受け入れられているのです。 ソフトウェア設計者は,ソフトウェアのビルド・サイクルにおける単純な経済的理由から,自身の設計を検証する公式の方法論を採用,あるいは運用していないだけなのです。

2つ目の啓示: 設計をビルドしてテストを行うだけであれば,何よりも安価かつ簡単に行うことができます。 何度ビルドを行うのかなど気にかける必要もありません。 こういったものは時間という観点では無いに等しいものであり,使用したリソースはビルドを破棄した際に完璧に回収できるのです。 テスティングとは現在の設計を正しいものにするということだけではなく,設計の洗練プロセスの一部でもある点にご注意ください。 複雑なハードウェア・システムのエンジニアは,しばしばモデルを構築します(あるいは少なくともコンピュータ・グラフィックスを用いて自らの設計をビジュアルに表現します)。 これによって設計者は,設計自身をレビューするだけでは見つけ出すことのできなかった設計の「感触」を得ることができるようになるわけです。 しかし,ソフトウェア設計ではこういったモデルの構築など不可能であり,かつ不必要なことでもあるのです。 私たちは単に製品自身をビルドすれば良いのですから。 公式のソフトウェア検査がコンパイラのように自動化されて存在していたとしても,私たちはビルド/テスト・サイクルを行うことになるはずです。 このため,公式の検査はソフトウェア業界にとって実用的な利益をさほど生み出さないのです。

これが今日のソフトウェア開発プロセスを取り巻く現状です。 さらに,より複雑なソフトウェア設計が,どんどん増加する人員や組織によって生み出されています。 そして,こういった設計は,何らかのプログラミング言語でコーディングされ,ビルド/テスト・サイクルを介することで検証,洗練されています。 こういったプロセスは,誤りを生み出しやすいものであり,取り立てて厳格というわけでもありません。 多くのソフトウェア開発者は,これが問題を大きく悪化させる方法であることを信じたくないと思っているのが現状なのです。

現在ある大半のソフトウェア開発プロセスは,ソフトウェア設計の様々なフェーズを細分化しようとしています。 コードを書き始める前には,最上位の設計を完了させ,凍結しておかなければなりません。 そして,テスティングとデバッギングは,製造時の過ちを除去するためだけに必要なものとされます。 中間にいるのはプログラマ,すなわちソフトウェア産業における建設労働者です。 そして多くの人々は,プログラマが「ハッキング」や「再設計」という行為を止めれば,ソフトウェア開発は本当に工学分野として成熟すると信じています。 プロセスが工学と経済の現実を無視している限り,工学分野としての成熟はあり得ないというわけです。

例えば,製造プロセスにおいて,再作業率が100%を越えてしまうことを許容するような近代産業は存在していません。 最初から正しく建築することのできない建設作業者は,たいていの場合,すぐに仕事を失ってしまうことになるわけです。 ところがソフトウェアの場合,どんなに短いコードであってもテスティングやデバッギング期間中に改訂されたり,書き直されるということがよく行われています。 私たちは,この種の洗練を設計のような創造的プロセスでは受け入れ,製造プロセスでは受け入れようとしないのです。 エンジニアが最初から完璧な設計を作り出すことなど,誰も期待していないわけです。 そういったことをエンジニアができたとしても,それが完璧であることを証明するためだけの洗練プロセスが用意されることになるのです。

日本のマネジメント・テクニックを学んだのであれば,プロセス中で発生した過ちについて作業者を非難しても,それは生産性を低下させるだけであるということを学んでいるはずです。 ソフトウェア開発を正しくないプロセス・モデルに適合させようとするのではなく,プロセスを改訂し,より良いソフトウェアを製造する上での支援となるようにしなければならないのです。 これが「ソフトウェア工学」のリトマス試験です。 工学とはプロセスの実行方法について論じるものであり,最終設計ドキュメントを作成するためにCADシステムが必要であるかどうかを論じるものではないのです。

ソフトウェア開発では,「すべて」が設計プロセスの一部になっているという大きな問題があります。 コーディングは設計であり,テスティングとデバッギングも設計の一部であり,私たちが一般的にソフトウェア設計と呼んでいるものもやはり設計の一部なのです。 このため,ソフトウェアのビルドは安価であるものの,設計は驚くほど高価になるのです。 ソフトウェアはあまりにも複雑であるため,設計時に考慮すべき側面は多岐にわたり,設計結果を評価する上での側面も数多く存在します。 そして問題は,様々な側面すべてが相互に関係している(ハードウェア工学における場合と同じように)という点にあります。 上位レベルの設計者が,モジュール内のアルゴリズム設計に関する詳細を意識しなくても良いのであれば,何も問題はありません。 同様に,プログラマがモジュール内の内部アルゴリズムを設計する際,上位レベルの設計を意識しなくても良いのであれば,何も問題はありません。 しかし残念なことに,様々な設計層における側面が互いに干渉しあうのです。 あるモジュールに対するアルゴリズム選択は,上位レベルの設計時に考慮した側面と同じくらい重要なものであり,ソフトウェア・システムの全体的な成功を左右するものとなり得るわけです。 ソフトウェア設計における様々な側面の間には,重要さの序列など存在していないのです。 最下位のモジュール・レベルで設計を間違えることは,最上位レベルでの間違いと同じくらい致命的なものとなるわけです。 つまり,ソフトウェア設計はすべての側面において完璧かつ正しいものになっていなければならず,そうなっていない場合,その設計に基づいたソフトウェアのビルドすべてが間違ったものとなってしまうのです。

ソフトウェアの設計は,複雑さに取り組むため,階層に分けられます。 しかし,プログラマがあるモジュールの詳細設計を行う際には,同時に考慮することなどできない数百ものモジュール,数千もの他の詳細が存在する場合もあるのです。 例えば,ソフトウェア設計の際に,美しい形でデータ構造やアルゴリズムに落とし込めないような重要な側面が存在します。 プログラマがコードの設計を行う際,理想的には設計におけるこういった他の側面を気にしなくても良いようにするべきなのです。

しかし,こういったことはうまく行きません。 そして,それにはちゃんとした理由もあります。 ソフトウェア設計はコーディングが完了し,「かつ」テストされるまでは完璧にならないのです。 そして,テスティングは設計の検証と洗練を行うプロセスにおける礎となるものです。 上位レベルの構造を設計しただけでは,完全なソフトウェア設計とは言えません。 これは詳細設計に向けた単なる構造上のフレームワークでしかないのです。 そして,上位レベルの設計を厳格な形で検証できるほど,私たちの能力は優れていないのです。 詳細設計は,少なくとも詳細設計以外の要因と同じくらい上位レベルの設計に影響を与えます(影響を与えられるようにしておくべきなのです)。 設計におけるすべての側面が,設計サイクルを通じて洗練されなければならないのです。 設計における一部の側面が洗練プロセス中で凍結されている場合,最終設計が貧弱な,あるいは機能しないものとなったとしても,それは別に不思議なことでも何でもないのです。

上位レベルのソフトウェア設計をより厳格な工学プロセスにできるのであれば何も問題はないのですが,現実世界のソフトウェア・システムはこのように厳格なものではありません。 ソフトウェアは複雑さを極め,あまりにも多くのものごとが相互に依存しあっているのです。 ハードウェアによっては設計者の思い通りに動作しないかもしれません。 また,ライブラリ・ルーチンにドキュメント化されていない制限があるかもしれません。 この種の問題は,すべてのソフトウェア・プロジェクトが遅かれ早かれ遭遇するものなのです。 またこの種の問題は,初期に発見される機会がないため,(ちゃんとしたテスティングを行った場合)テスティングの最中に発見されるものなのです。 こういった問題が発見された場合,設計の変更が余儀なくされるわけです。 運が良ければ,設計の変更は局所的なものとなるでしょう。 しかし多くの場合,変更はソフトウェア設計全体の重要な部分を切り裂くことになるのです(マーフィーの法則です)。 そして何らかの理由によって,影響を受ける設計部分が変更できない場合,他の部分でこれを吸収することになり,結果的にその部分が脆弱なものとなるのです。 マネージャは,これを「ハッキング」と認識するわけです。 しかし,これがソフトウェア開発の現実なのです。

この前にいたプロジェクトで,内部モジュールAと内部モジュールBの間にタイミング依存が発見された時のことです。 残念なことに,抽象化によってモジュールAの内部は隠蔽されており,正しい順でモジュールBの起動を行うように対応することは許されませんでした。 つまり問題が発覚した段階では,Aの抽象化をやり直すにはもう遅すぎたのです。 そして予想通り,Aの内部設計に合わせる形で,複雑な一連の「修正」が施されることになりました。 初期バージョンの調達前に設計が壊れてしまったことを,全員が感じ取ることになったのです。 また,その後の修正は,今までの修正指針と矛盾することが多くなりました。 これが一般的なソフトウェア開発プロジェクトなのです。 最終的に,私は同僚とともに設計の変更を叫ぶことになったのですが,マネジメントからの同意を得るためにサービス残業を行う羽目になったのです。

一般的な規模のソフトウェア・プロジェクトであれば,必ずこういった問題が発生するはずです。 そして,こういったことを防ぐために様々な試みをすればするほど,重要な詳細が見過ごされていくことになるのです。 これが技芸と工学の違いです。 私たちは経験することによって正しい方向に向かうことができるのです。 これが技芸というものなのです。 経験のみが海図のない領域に私たちを連れて行ってくれるのです。 その後で,管理された洗練プロセスによって,私たちが得たものをより良いものにしていくべきなのです。 それが工学というものなのです。

ソフトウェア設計ドキュメントは,コーディング前に記述するのではなく,コーディング後に記述した方がずっと正確になります。 これは,プログラマであれば誰でも知っていることです。 この理由は明らかでしょう。 コードに反映された設計のみが,ビルド/テスト・サイクルを通じて洗練されてきた唯一の最終設計なのです。 このサイクルを通じて初期設計が変更されない確率は,プロジェクト中のモジュール数やプログラマ数の逆数と相関関係があります。 つまり,この数値は急速にゼロへと近づいていくのです。

ソフトウェア工学では,すべてのレベルにおいて優れた設計が必要なのです。 上位レベルでは,特に優れた設計が必要となります。 初期設計が優れているほど,詳細設計も優れたものになるためです。 このため,設計者は役に立ちそうなものをすべて採用するべきです。 構造化チャート,Boochダイアグラム,状態遷移テーブル,PDL(訳注: Program Design Language---いわゆる疑似コードのこと)等---それが役に立つのであれば何でも採用することです。 しかし,こういったツールや記法がソフトウェア設計ではないということは,常に心に留めておかなければなりません。 最終的に,私たちは真のソフトウェア設計を作り出さなければならず,それは何らかのプログラミング言語となるためです。 したがって,私たちが設計を作り出す際に,コーディングをためらう必要はないのです。 私たちは,必要に応じて設計を洗練しなければならないというだけなのです。

現時点では,上位レベルの設計と詳細設計の双方に適した設計記法など存在していません。 設計は,最終的に何らかのプログラミング言語でコード化されることになります。 このことは詳細設計を開始する前に,上位設計記法による結果を対象となるプログラミング言語に変換しなければならないということを意味しています。 この変換には時間がかかり,変換によってエラーが生み出されることにもなります。 また,選択したプログラミング言語とうまく対応付けられていない設計記法から変換を行うような場合,プログラマは要求レベルにまで遡り,上位レベルの設計をやり直し,それに従ってコーディングを行うこともしばしばあります。 こういったこともまたソフトウェア開発の現実として存在しているのです。

元々の設計者が初めからコードを記述した方が,誰か他の担当者に任せてしまうよりも良いはずです。 このため,私たちに必要なのは,すべての設計レベルに適切となる統一記法なのです。 言い換えれば,私たちは上位レベルの設計コンセプトを捕捉できるようなプログラミング言語を必要としているのです。 ここにC++の入り込む余地があるわけです。 C++は現実世界に存在するプロジェクトに適したプログラミング言語であり,より表現力の豊かなソフトウェア設計言語でもあるのです。 つまり,C++を使えば設計コンポーネントに関する上位レベルの情報を直接表現できるようになるわけです。 これによって,設計の作成が容易になり,その後の洗練も容易になります。 そしてC++の提供する強い型チェック機構により,設計誤りの検出プロセスも支援されます。 これによって設計はより堅牢なものとなり,ひいては優れた工学的設計を実現することが可能になるのです。

ソフトウェア設計は最終的に何らかのプログラミング言語で表現され,その後ビルド/テスト・サイクルを通じて検証,洗練されなければなりません。 それだけのことなのです。 過去に人気を博してきたソフトウェア開発ツールやテクニックを思い起こしてください。 構造化プログラミングは,ある時期におけるブレークスルーでした。 そして,構造化プログラミングはPascalによって普及し,それによってPascal自身も普及することになったのです。 オブジェクト指向設計は新たな潮流であり,C++はその中心に位置しています。 では次に,人気を博さなかったものを思い起こしてみましょう。 CASEツール? 確かに普及しましたが,普遍的なものにはなっていません。 構造化チャート? これも同じでしょう。 同様にWarner-Orrダイアグラム,Boochダイアグラム,オブジェクト・ダイアグラム等が出てくるかもしれません。 それぞれには長所があるものの,それぞれは本当のソフトウェア設計ではないという共通した短所を抱えているのです。 実際,広範囲に普及しているといえるソフトウェア設計記法はPDLだけであり,それが私たちの目にどのように映っているのかを考えてみる必要があるでしょう。

このことは,プログラミング・テクニック,そしてとりわけ現実世界におけるプログラミング言語の改善がソフトウェア業界において最も重要であるという点を,ソフトウェア業界全体が本能的に理解していることを意味しています。 またこのことは,プログラマが設計に興味を持っているということも意味しているのです。 より表現力豊かなプログラミング言語が利用可能になれば,ソフトウェア開発者はそれを採用するのです。

さらに,ソフトウェア開発プロセスがどのように変遷してきたのかを考えてみてください。 昔々,私たちはウォーターフォール・プロセスを実践していました。 そして今では,スパイラル開発やラピッド・プロトタイピングについて論じています。 こういったテクニックの目的として,しばしば「リスクの低減」や「製品出荷の短期化」等が主張されているものの,本当のところはライフ・サイクル中でのコーディング作業を早期に開始するための口実でしかないのです。 しかし,これは正しいことです。 これによって,設計を早期に検証,洗練するためのビルド/テスト・サイクルが開始できるようになるわけです。 またこのことは,上位レベルの設計を担当したソフトウェア設計者が詳細設計時点までいるという状況を生み出しやすくするわけです。

上述したように,工学とは最終的な製品がどのようなものになるのかということではなく,あなたがどのようにプロセスを実践するのかということなのです。 このためソフトウェア業界にいる私たちは,エンジニアに近い位置にいるものの,いくつか認識を変更する必要があります。 プログラミングとビルド/テスト・サイクルが,ソフトウェア開発における工学プロセスの中心となるのです。 私たちは,これらの作業を正しく実践していく必要があるわけです。 ビルド/テスト・サイクルの経済,およびソフトウェア・システムは現実的にどのようなものでも表現できるという事実を考えた場合,ソフトウェア設計を検証できるような汎用手法が見つかることなどあり得ないのです。 私たちはプロセスを改善できるだけで,この状況から抜け出すことなどできないのです。

最後の指摘です。 どのような工学設計プロジェクトでも,その目標は何らかのドキュメント作成になります。 ただ,実際の設計ドキュメントが最も重要であることは論を俟たないものの,製造しなければならないものはそれだけではないはずです。 最終的に誰かがそのソフトウェアを使用することになるのです。 また,たいていの場合,そのシステムは後で修正,改訂しなければならないのです。 つまり,ハードウェア・プロジェクトと同様に,ソフトウェア・プロジェクトにとっても補助ドキュメントは重要なものになるわけです。 そして,設計プロセスに直接関係しないユーザ・マニュアル,インストレーション・ガイド,その他のドキュメントを当面無視したとしても,補助設計ドキュメントに関して解決しなければならない2つの重要なニーズが依然として存在しているのです。

補助ドキュメントの用法の1つとして,設計に直接組み込まれることのない,問題領域からの重要な情報を捕捉するというものがあります。 ソフトウェア設計とは,問題領域におけるソフトウェアのコンセプトからモデルのコンセプトを創造するという作業が含まれています。 このプロセスでは,問題領域に対するコンセプトの理解を確立しなければなりません。 通常の場合,こういったことを行うには,ソフトウェア空間中に直接モデル化する必要のない情報まで理解しておく必要がありますが,これによって本質的なコンセプトが何であるか,そしてどのようにモデル化するのが最適なのかということを設計者が確定できるようになるわけです。 つまり,後でモデルを変更する必要が生じた場合に備えて,こういった情報をどこかのタイミングで捕捉しておくべきなのです。

補助ドキュメントのもう1つの重要な用法とは,設計自身から直接抽出することが難しい,設計上の側面をドキュメント化しておくというものです。 こういったものとして,上位レベルおよび下位レベル双方の側面が含まれる可能性もあります。 こういった側面の多くは,図表として表現するのが最適なのです。 このため,ソースコード中のコメントとして記述することが難しくなるわけです。 しかしこのことは,プログラミング言語の代わりにグラフィカルなソフトウェア設計記法を使用するべきであるという議論「ではありません」。 これでは,ハードウェア分野の設計図に文字の説明が必要であるという主張と何ら変わりはありません。 真の設計を決定付けるのは,補助ドキュメントではなく,ソースコードであるということを忘れてはいけないのです。 将来的には,ソフトウェア・ツールによってソースコードという設計から,補助ドキュメントが生成されることになるのかもしれません。 しかし,これはおそらく高望みというものでしょう。 次善の策としては,プログラマ(あるいはテクニカル・ライタ)がソースコードから特定の情報を抽出し,その後,何らかの手段でそれをドキュメント化する作業を支援するようなツールができるかもしれません。 しかし,こういったドキュメントを手作業で最新に保ち続けるというのは,かなり難しいことになるはずです。 これは,さらに表現力豊かなプログラミング言語が必要であるという,もう1つの議論なのです。 また,こういった補助ドキュメントを最小限に抑えておき,プロジェクト後半までできる限りそれを非公式なものにしておくという議論でもあります。 ここでも,私たちはより良いツールを期待できるかもしれません。 そうでなければ,私たちはいつまでも鉛筆,紙,ホワイトボードを使い続けることになるでしょう。

要約すると