ソフトウェア設計

Team CHAO


イントロダクション

"ソフトウェア設計"ということばは、コンピュータプログラムに対する要求を実際に動作するプログラムにするための構想、創造、くふうという意味で使われます。設計は決定論的ではなく発見的過程であり、創造性と洞察力を必要とします。規模の大小に関わらず、注意深い設計はプログラムに大きな利益をもたらすものなのです。

設計のレベル

先の「プログラミング方法論」でも述べたように、ソフトウェアを設計するに当たっては、プログラムを各要素に分解して考えると比較的考えやすくなります。ここではより詳しく、ルーチンとモジュールについての概念について触れてみたいと思います。

”ルーチン”や”モジュール”という単語は、いろいろな状況で様々な意味を持つ柔軟な単語です。この章の用法では、ルーチンとは、ある目的をもって呼び出されるメソッドのことです。また、モジュールは、データとそのデータに作用するルーチンの集合体です。モジュールは、共通するデータは持たないが、一連の凝集したサービスを提供するルーチンの集合体である場合もあります。

ただし、ルーチンとメソッドとは必ずしも一対一の関係ではありません。概念が違うのです。簡単に言うと、アプリケーションの中にモジュールがあって、モジュールの中にルーチンがあるのです。ルーチン、モジュールはあくまでも区分けの概念で、ルーチンの中に何があるか、モジュールの中に何があるかはプログラムの作り方によります。次にソフトウェア設計のレベルを示した図を示します。

レベル1:サブシステムへの分割

このレベルにおける設計作業の中心は、プログラムを主要なコンポーネントにいかに分割するかを決め、コンポーネント間のインターフェースを決めることです。

レベル2:モジュールへの分割

このレベルにおける設計には、システムの全てのモジュールを定義します。分割したモジュールが複雑である場合には、それをさらに分割してモジュール化します。

モジュールが明示されるのと同時に、システムのほかの部分とモジュールとのやり取りの詳細も指定します。このレベルでの作業によりサブシステムはそのモジュールを実際に作成するのに十分なだけの詳細なレベルまで分割されます。

レベル3:ルーチンへの分割

このレベルにおける設計には、モジュールをモジュールにより提供されるサービスに分割することが含まれます。ルーチンにすべきものが見つけられるのと同時に、その機能も決定されます。モジュールはそのサービスルーチンを通じてシステムの他の部分とやりとりします。

レベル4:内部ルーチンへの分割

一般的に内部ルーチンの設計は、それぞれのルーチンを作成するプログラマに任されます。コンピュータプログラムは、このレベルの設計作業なくしてはありえません。

どのような設計手法を用いるべきか

ソフトウェア設計の具体的な手法には、構造化設計やオブジェクト指向設計などがあり、それぞれに特徴があります。構造化設計もオブジェクト指向設計も含めて、一般的な設計手法には、大抵次の2つの主たる要素が含まれています。

設計の主要な部分はプログラムを小さなサブプログラムに分解するということになりますが、きちんとした構造を特定したところで正しい設計を止めなければならないということではありません。いかなる手法も全ての創造に適用できるわけではないので、自分が選択できる道具をうまく使いわけることが必要です。そして、それぞれの長所を生かし、短所を補完できるように効率的にそれぞれの手法を使用できれば最大限の結果を得られることと思います。構造化設計とオブジェクト指向設計の詳細については別の章で触れることにします。

周遊設計

主要な設計を組み合わせて 使用することは可能であり、それぞれの長所を生かして弱点を最小にすることができます。それぞれのアプローチはプログラマの道具ですが、道具にはそれぞれふさわしい仕事があります。それらのアプローチの発揮するいずれかの、あるいはすべての能力を探しあてることで、これを役立たせることができます。

”周遊設計”とは、設計は繰り返しのプロセスであることを示しています。試行的な設計を繰り返して異なるアプローチを試すうちに、ハイレベルからの見通しとローレベルからの見通しの両方が分かってきます。ハイレベルからの大きな眺めはローレベルでの詳細の援助となり、ローレベルの詳細事項は、ハイレベルでの決定事項の確固たる支えとなります。支え合うことで、トップダウン単独あるいはボトムアップ単独によってシステム全体を仕上げるより、より安定した構造を作り出すことができるのです。

また、きちんとした設計に重要なことは、それが発見的なプロセスであるということを認識することです。設計は、常にいくらかの試行錯誤を伴います。そして、もっとも重要なことは、ひとつの手法にこだわらないことです。宗教のようにひとつの手法に固執することは創造性を損ないプログラムを傷つけます。設計手法に対して少しこだわることは手法を良く理解することにつながり利益があります。しかし、頑固であってはいけません。一生懸命努力してもうまくいかないときは、しばらく問題を心から離すことで、根を詰めすぎるよりもすばやく良い結果を得られることがあります。

設計のあるべき特性

優れた設計には、いくつかの一般的な特性があります。それらの目標をすべて達成しているのなら、その設計はすぐれたものと言えます。設計における信頼性、パフォーマンスなどの性質は、同時にプログラムの性質でもあります。次に設計そのものの特徴を挙げます。

優れた管理ができること

優れた管理の可能性は、どのようなシステムにおいても第一の目標です。システム全体の一貫性に欠く事のできないものであり、プログラマがシステムを立ち上げるのを容易にし、後の保守も容易にします。

複雑さが少ないこと

複雑さが少ないことは管理がしやすいことなので、上と同様に重要な特性です。

保守が容易であること

プログラムの保守をするプログラマがコードに対して何を思うかに配慮し、システムを自己解説型に設計する。

サブプログラム間の連結が最小になること

ルーチン化、情報隠蔽などの原則を適応して、システムの内部結合が少なくなるように設計します。これにより、システム生成、検査、あるいは保守での作業を最小化できます。

拡張可能性

これは、既存の構造を壊すことなくシステムの増強を行えることを意味します。システムの全体に影響を与えることなく、一部だけを変更可能にすることです。

再利用可能性

再利用可能性とは、システムを構成する一部分を他のシステムでも利用できるようにシステムを設計することで、最近のプログラムのキーワードになっています。

高いファンイン

ファンイン ( fan-in ) とは、ひとつのルーチンが多くのルーチンから利用可能であるということです。ファンインが高いということは、システムのローレベルのルーチンの設計が適切であるということを示しています。

なるべく低いファンアウト

低いファンアウト (fan-out) とは、ひとつのルーチンが呼び出すルーチンの個数が少ないということです。ファンアウトが高いと、ルーチンが他の多くのルーチンを制御することを意味し、従って理解することが困難になります。

ポータビリティー

ポータビリティーとは、移植可能性のことであり、システムを容易に他の環境にもっていくことができるように設計することを意味します。

スリムさ

これは、余分な部分がないようにシステムを設計するということです。余分なコードでも、開発、検討、検査、保守、理解そして変更時には考慮されなければならないからです。

階層化設計

階層化設計とは、分解のレベルを階層化し、それぞれのレベルでシステムを把握できるようにし、また一貫したシステム把握ができるようにすることです。

標準テクニック

標準的なテクニックを使用することは望ましいことです。システムがトリッキーなテクニックを使用しているということは、それを理解するには時間がかかることを暗示しています。

まとめ

これまでにも幾度となく述べてきたように、設計手法とはプログラマーの道具のようなものです。その道具をどれだけ上手に使用するかが、ひいてはプログラムの質を決定するといっても良いでしょう。悪い設計手法を用いて良いプログラムを作ることもできますし、良い設計手法を用いて悪いプログラムをつくることもできるのです。ただしいうまでもなく、良い道具は高品質なソフトウェアを作ることを容易にするので、良い道具を選ぶことはもちろん重要なことです。


Editor : Kota Iguchi ( kota@sysportcore.com )