オブジェクト指向設計帖
巻之一 設計とは何ぞや
株式会社 オージス総研
オブジェクト・テクノロジー・ソリューション部
林 俊樹
Hayashi_Toshiki@ogis-ri.co.jp

目次

一、はじめに
二、設計とは何か
二 ノ 一、設計で取り扱う問題
二 ノ 二、解はどう導き出されるか
三、設計の意義
四、設計図の役割
四 ノ 一、設計図の意義
四 ノ 二、意思疎通する利点
五、まとめ
六、参考資料

一、はじめに

ソフトウェア開発において、設計は必要でしょうか。
この問いに対して、多くの人は必要だ、と答えると思います。より大規模で複雑なソフトウェア開発になるほど、設計の必要性が高くなるのは、おそらく事実でしょう。

では、なぜ設計をするのでしょうか。
この問いに対し、設計を生業とし、日常的にそれを行っている技術者にあっても、明快な回答ができる人は、どれ程いるのでしょうか。
かくいう私も、オブジェクト指向技術について学び始めた頃は、そのような疑問に思い至りませんでした。設計は、継承、多態、カプセル化などのオブジェクト指向の基本概念や、 UML の基本的な表記法さえ覚えれば、多少はできるものと考えていたのです。今にして思えば、これはまったくの妄想と言うしかありません。

本稿では数回の連載を通して、オブジェクト指向設計という、ともすれば遠大なテーマを取り上げ、考察を進めて行こうと思います。
対象となる読者は、オブジェクト指向についての入門書を読み終えて、もう少し設計についての知識を掘り下げたい方、あるいは、実際にオブジェクト指向設計を行っているが、いまいち自信が持てないので、設計を行う上での視点を増やしたい方を想定しています。
初回である今回は、まず設計自体について、どのようなものなのか、なぜ設計を行うのか、について考えます。

ここで取り上げる設計とは、主にソフトウェアアーキテクチャに関する内部設計のことを指します。したがって、ユーザインタフェースや帳票などに関わる外部設計に関しては、ここでは取り上げません。

二、設計とは何か

そもそも、設計とは何なのでしょうか。
ソフトウェア開発では、設計はふたつの意味合いで使われています。

ひとつは、分析作業で獲得した、ソフトウェアが扱うべき問題の解について考察することです。
もうひとつは、考察した解を図面によって表す作業、つまり、設計図を記述することです。
前者は作業それ自体を指し、後者は作業を実行した結果の成果物を指します。

前者について見てましょう。この意味合いをもう少し具体化すると、分析では問題を規定する、すなわち、ソフトウェアに「なにが必要か」を規定し、設計では問題の解、すなわち、「どう実現するか」について規定する、と理解できます。

二 ノ 一、設計で取り扱う問題

ここで、ソフトウェアが扱うべき問題とは何か、ということを、もう少し踏み込んで考えないと、話が進まないことに気づきます。問題、別の言葉で表現すれば、ソフトウェアで解決を要する事項とは何か、ということです。
通常、我々がソフトウェア開発を行うのは、ソフトウェアに何か仕事をさせ、ユーザが目標を達成するのを助けるためです。つまり、ソフトウェア開発は、ユーザが必要とする機能を付与することに関心が向けられていると言えるでしょう。

では、ここで扱う問題とはソフトウェアの機能に対する要求、すなわち、機能要件であるか、というと、それでは不十分なのです。設計では、その他の要件、技術要件および品質要件も満たす必要があるからです。
技術要件とは、ハードウェアやソフトウェアに対する要件のことです。たとえば、対象とするプラットフォーム、採用技術、機器構成、ROM/RAMの容量などが挙げられます。
品質要件とは、ソフトウェアの品質特性に対する要件のことです。品質特性の代表的なものとしては、ISO/IEC 9126 で定められているようなものがあります。ついでにいえば、ISO/IEC 9126 では、品質を6つの特性、すなわち、機能性、信頼性、使用性、効率性、保守性、移植性に分類して定義しており、これら特性にはさらに細分化された特性が存在します。ただし、品質要件として、顧客から明示されるものはそれほど多くはありません。しかし、設計者は暗黙的な品質要件にも関心を向けなければならないのです。
要件というと、ともすれば、機能要件や技術要件へ意識が集中しがちですが、これらの要件は等価として扱われるべきであり、設計においても意識的な関心を寄せることになります。
つまり、設計で取り扱うべき問題とは、機能要件(業務要件とも言う)、技術要件、品質要件の3つであるといえるでしょう。
オブジェクト指向の世界では、このような問題は、ユースケース記述や、ドメイン分析モデル、アーキテクチャ分析モデルなどで表現されます。

二 ノ 二、解はどう導き出されるか

さて次は、問題に対する解をどう導き出すか、ということになります。現実においては、ソフトウェアで扱わなければならない問題は複雑なのが常です。こうした複雑な問題を一気に消化しようとすると、確実に消化不良を起こします。つまり、出された問題についてすべてを同時に捉えるというのは、人間のなしうる業ではないのです。
一般的に、人間が一度に認識できる要素は7±2ないし5±2などと言われています。ここで重要な点は、人間が一度に理解できる量には限界があり、しかも、それほど多くはないという事実なのです。
そこで問題を、人間が理解できる程度に、全体を適切な部分に分割するのですが、その際に、どのような観点で分割するか、ということが重要になってきます。
この観点は設計手法に依存します。
たとえば、構造化設計手法であれば、対象とする問題を構成する機能に着目し、機能を果たすアルゴリズムを導出します。オブジェクト指向設計であれば、対象とする問題を構成する個々の責務に着目し、責務を果たすクラスを導出します。加えて、オブジェクト指向では、問題をさらに抽象化、階層化します。
オブジェクト指向設計では、このクラスの導出を、いかに上手く行うかということに設計者の設計手腕が問われるのです。皆さんにとっては、設計の醍醐味、私にとっては、悩みの種、と言ったところでしょうか。
残念ながらクラスの導出の方法には、唯一の方法というのは存在しません。とは言え、導出する際に考慮したほうが良い「視点」であれば存在します。この「視点」に関して、本連載を通じて少しずつ紹介していくつもりです。

三、設計の意義

設計とは何か、ということについて考えました。しかし、それでも疑問は残ります。なぜ設計をするのか、ということです。
先ほど、設計は問題に対する解を表現する手段と定義しました。しかし、それはコードにも同じことが言えるはずなのです。そして、システムを動作させるという視点で考えると、実際に動くコードの方が重要であり、設計をしなくてもシステムは動作します。
それでも、ソフトウェア開発においては、設計は重要なアクティビティと捉えられています。それは、いったい何故なのでしょうか。

ここでは、考察にあたって逆説的なアプローチを用います。つまり、設計を行わずコードから記述した場合にどうなるか、ということを考えてみましょう。
具体例として、私自身の苦い経験に基づいた話を紹介します。

若かりし頃、私はちょうどプログラム言語を覚えたてで、プログラムが動くのが楽しく、ただ一心不乱にコードを記述していました。動くプログラムが完成すると、いろんなことをさせてみたくて、プログラムにいろいろな機能を追加していきます。既存のコードに、拡張を加えていくのですが、当時はプログラム初心者なので、サブルーチンを用いてコードを分割するなんて知恵はもちろん働きません。ただ単純にコードを、必要な箇所に追加するだけなのです。その結果、膨大なステップ数を誇る main 関数ができあがりました。
ある時、プログラムが動かなくなったのです。それで、デバッグをするためにコードをチェックしたのですが、なにしろ相手は、コードがスパゲッティのように複雑に絡み合った main 関数なので、一筋縄では行きません。やっとの思いで、修正すべき箇所を特定したのですが、そのコードは、地雷のようにいろいろな所に散りばめられているのです。
その箇所を直すと、今度は違う条件下で、またプログラムが動かなくなり、さっきと同じように発生源の在り処を探します。すると、また違う条件下で動かなくなり・・・。以下、無限ループ。
結局、泣く泣くそのコードを捨てる羽目になり、最初から作り直すことになりました。

一体、何がいけなかったのでしょうか。その理由はいくつか考えられます。

第一に、同じコードが複数の箇所に点在していること。そのコードに間違いがあった場合、すべての箇所に修正を施さなければならないのですが、その際に修正漏れが発生する可能性があり、新たなバグの温床になります。

第二に、ひとつの関数で複数の機能を実装していること。そのような関数は非常にコードの見通しが悪くなります。それにより、コードを把握することが困難になりやすく、不具合の発生源の特定に難渋すること必至です。

第三に、コードが複雑に絡み合っていること。コードが微妙な均衡のうえに成り立っているので、どこか修正すると他の箇所が非常に高い可能性で動作しなくなります。

このコードは個人的に作成したものなので、被害は私だけで収まりましたが、これが大規模プロジェクトで適用された場合はどうでしょうか。まさに阿鼻叫喚、悪夢としか言い様がありません。
この話は例としては極端に思えますが、この例を小規模にしたようなコードは、実際のプロジェクトでも見かけることがあります。そして、そのようなプロジェクトでは、そのコードのおかげで、大なり小なり被害を被っています。

ここで設計が登場することになります。オブジェクト指向設計では提示された問題を、適切な粒度に分割、抽象化、階層化します。そうすることにより、先程の例のような混沌としたコードに秩序を与えることができます。つまり、ソフトウェアが持つ複雑性を管理できるのです。では、複雑性を管理することによりどのような利点があるでしょう。
突き詰めると、設計にはコードの冗長性を排すること、そして同じような責務や機能をグループ化することにより、人がコードを理解するのを容易ならしめるといった利点があります。

四、設計図の役割

今度は、設計のもう一つの意味合い、設計図を記述すること、について考察します。
最近のオブジェクト指向設計では、ほとんどの設計者がUMLダイアグラムを用いて設計図を記述すると思います。UMLを用いて、クラス図などで静的な側面を、相互作用図などで動的な側面をそれぞれ記述し、ソフトウェア・アーキテクチャを表現していきます。

四 ノ 一、設計図の意義

では、なぜ設計図を記述する必要があるのでしょうか。
私は、設計図を記述する必要性に関して、大きく分けると二つ存在すると考えています。
一つは、自分の考えを整理するため、もう一つは、相手と意思疎通を図るためです。
前者は、前述した人間の認知能力に起因しています。特に、私の場合、ソフトウェアで扱うべき問題よりも、頭の中身が混沌としているので、その時々の思考を図や文章として書き出し整理しながら、設計を考えることにしています。
後者は、複数人で設計をする場合や、設計者と実装者が異なる場合などは、非常に重要だといえるでしょう。この場合、相手に何を理解してもらいたいか、を意識して図を記述する必要があります。
以下、後者について考察していきましょう。

四 ノ 二、意思疎通する利点

設計図を用いて相手と意思疎通することで、設計者はいくつかの利益が得られます。

第一に、自分で実装しなくても済むこと。大規模なソフトウェア開発になる程に、設計者と実装者を分けなければ、疲労困憊することはほぼ間違いありません。設計図を用いて、設計者と実装者の意思統一を図ることができれば、自分で実装をしなくて済むはずです。

第二に、設計を相手に引き継ぐことが可能であること。システムの開発から保守まで、一人の設計者がずっと設計に従事することは、そうそうありません。実際には設計者が入れ替わり立ち替り、ということになるのですが、その際の引継ぎ資料として設計図が必要になります。もし無ければ、口伝に頼るしかありません。しかし、この場合は情報が欠落していることが、ずっと後になって判明することが多いのです。設計の意図が判らない度に前任者を呼び付けていては、どちらにとってもたまったものではありません。設計図があることにより、安心して引き継ぐことが可能になります。

第三に、相手からフィードバックを受けること。一人の設計者が、全ての要件を満たして、且つ、エレガントな設計ができれば大変結構なことです。しかし、現実問題として、そのようなことは、ほとんどありません。設計を相手に見せることにより、他の視点で設計を見てもらうことが可能になります。そのことにより、設計の質が向上するでしょう。また、設計から新たな要件がでてくるのは、ままあることなので、設計者はフィードバックを迅速に受けた方が、設計者も、後々に楽ができるはずです。

もし設計図を用いない、というのであれば、意思疎通をする手段は、自然言語もしくはコードを用いてということになります。しかし、自然言語では曖昧な部分が多く、コードでは情報が詳細すぎて全体を把握するのは困難です。これらと比べてUMLダイアグラムで描く設計図の利点は、一目で見て概要が把握できることだと言えるでしょう。
設計図というと、CASEツールで綺麗に清書したUMLダイアグラムを連想してしまいがちですが、メモ用紙に書いたような簡単なものでも構いません。要は、上掲のような利点が得られれば良いのです。

五、まとめ

まず、設計は、どのようなものであるか、ということを明らかにしました。

次に、設計の必要性に関して明らかにしました。

最後に、設計図を記述する意義について明らかにしました。

さらに、設計図を用いて、相手と意思疎通することによる利点について明らかにしました。

以上、駆け足で設計の"what"と"why"について考察してみました。次回以降からは、設計の"how"の「視点」について考察していきたいと思います。
また、今回は初回ということもあり、いささか抽象的な内容になってしまいました。この点を鑑みて、次回以降では、UMLダイアグラムや、実装コードを掲載し、具体的な内容に踏み込むつもりです。なるべく、読者の興を削がないよう努力しますので、しばらくの間、お付き合い願えれば幸いです。
では、また次回にお会いしましょう。

六、参考資料

  1. 『オブジェクト指向入門』 Bertrand Meyer/著, 酒匂 寛・酒匂 順子/訳, 二木 厚吉/監訳 アスキー
  2. 『ソフトウェア工学』 Shari Lawrence Pfleeger/著, 堀内 泰輔/訳, ピアソン・エデュケーション
  3. 『オブジェクト指向再入門講座』 金澤 典子/著, SRC
  4. 『ソフトウェア アーキテクチャ』 Frank Buschmann・Regine Meunier・Hans Rohnert・Peter Sommerlad・Michael Stal/著, 金澤 典子・水野 貴之・桜井 麻里・関 富登志・千葉 寛之/訳, 近代科学社
  5. 『Booch法:オブジェクト指向分析と設計 第2版』 Grady Booch/著, 山城 明宏・井上 勝博・田中 博明・入江 豊・清水 洋子・小尾 俊之/訳, アジソン・ウェスレイ


© 2002 OGIS-RI Co., Ltd.
Index Next
Index Next