設計の原則
1 はじめに
プログラムの設計は非常に難しい.チームでの開発はもちろん,個人単位の設計であっても難しい.
単純にプログラムの設計と言っても,プログラム全体の設計,クラスの設計,関数の設計と様々である.
その中で,最も注目されるのはクラスの設計である.なぜなら,プログラムにおいて再利用する単位はクラスだからである.
しかし,クラスの設計が悪いと再利用をすることができない.だが,良い設計であれば自然と再利用が可能である.
そこで今回は,良いクラスを設計するために,何をすべきかについてまとめた設計の原則を紹介する.
2 設計の原則
設計の原則[1]とは,クラスを設計する際,自然と適応されるべき原則のことである.
2.1 何故,設計の原則を適応させるのか
プログラムは,一度リリースしたらそれで終わりではない.特に,ソフトウェア開発ともなれば,
開発が終了した後には,変更,保守の仕事に移ることになる.その際,プログラムが複雑で読解するのが困難であったら,
変更,保守を行うことができない.よって,変更,保守が可能で,読解することが容易なプログラムを目指すために設計の原則を適応させる.
2.2 6つの原則
クラス設計における6つの原則を紹介する.
2.2.1 単一責任の原則
クラスを変更する理由は1つ以上存在してはならない.クラスには1つの役割しか持たせてはならない.
単一責任の原則では,「役割(責任)=変更理由」と定義されている.
何故,変更する理由が1つでなければならないのだろう.それは,役割が複数あれば,その役割の数だけ変更理由になってしまうからである.
変更する理由が一つならば,変更点が明確になる.役割を見極めるのは難しいが,結合している役割を見つけそれらを分離する作業は,設計の本質である.
2.2.2 オープン・クローズドの原則
ソフトウェアの構成要素(クラス,モジュール,関数など)は拡張に対して開いて,修正に対して閉じていなければならない.
拡張に対して開かれているというのは,モジュールの振る舞いを拡張できるという意味である.
修正に対して閉じているというのは,モジュールの振る舞いを拡張しても,そのモジュールのソースコードやバイナリコードは影響を受けないという意味である.
しかし,閉じたモジュールであっても,閉じることのできない変更があることに注意してほしい.
2.2.3 リスコフの置換原則
派生型はその基本型と置換可能でなければならない.
リスコフの置換原則に違反すれば,オープン・クローズドの原則にも違反していることになる.
なぜなら,派生型は基本型のように振舞えなければならないからである.
例えば,派生型で定義した関数を基本型からどうやって使用するのだろうということである.
2.2.4 依存関係逆転の原則
上位のクラスは下位のクラスに依存してはならない.どちらのモジュールも抽象に依存すべきである.
抽象は実装の詳細に依存してはならない.実装の詳細が抽象に依存すべきである.
2.2.5 インターフェース分離の原則
クライアントに,クライアントが利用しないメソッドへの依存を強制してはならない.
利用しないメソッドに依存してしまうと,クライアントはそういったメソッドの変更の影響を受けやすくなる.
そういった,不本意な結びつきを避けるために,複数の役割を持ったクラスは,役割ごとの小さなインターフェースに分離すべきである.
2.2.6 最小知識の原則
友達の友達であるクラスと関係をもってはいけない.別名:デメテルの法則ともいう.
2.3 良い設計の要素
凝集性が高く,疎結合なクラスは再利用しやすい.
2.3.1 凝集性
責任がどの程度強く関係し集束されているかの度合いである.
凝集性の高いクラス
- プログラムが小さいので,理解しやすい
- ひとつの仕事をしているので,変更の影響を受けにくい
凝集性の低いクラス
- プログラムが大きいため,複雑で理解しにくい
- 複数の仕事をしているため,変更の影響を受けやすい
2.3.2 結合性
クラス同士の結びつきがどれほど強いかを計る度合いである.表1は結合の度合いを表にしたものである.
関係の種類
- 継承の関係
- コンポジション(包含)の関係
- 依存の関係
強い |
具象クラスの継承 |
|
具象クラスの包含 |
|
具象クラスへの依存 |
|
抽象インターフェースの継承 |
|
抽象インターフェースの包含 |
|
抽象インターフェースへの依存 |
弱い |
無結合 |
表1 結合性の度合い
2.4 悪い設計の要素
悪い設計の要素を紹介する.
1つの変更によってシステムの他の部分にも影響を与えてしまう,変更しにくい設計のことである.
1つの変更によって,プログラムの関係ない部分まで壊してしまう設計のことである.
他のプログラムでも再利用できる部分を切り離せないことである.
正しいことをするよりも,誤ったことをすることの方が容易なプログラムのことである.
本質的な意味を持たない無駄な構造を内包しているソフトウェアのことである.
同じような構造を繰り返し含み,まとめられる部分がまとまっていないことである.
読みにくく,わかりにくい.設計の意図が伝わらないクラスのことである.
悪い設計の中でも特に,硬さともろさはあらゆる手段を講じて避けてもらいたい.この2つの内1つでもあると変化に対応できなくなる.
悪い設計の要素が1つでもあることを設計の悪臭がするという.
3 設計の理想形
クラスの理想形は変化に対応できることである.
クラス設計における理想形(図1)の1つに,間接的にクラスを参照することが多い.
この設計は,結合性が低くなり,変更が容易になる.目標は,クリーン,シンプル,かつわかりやすくである.
あとで直すなどと決して言ってはならない.しかし,オープン・クローズドの原則のように対応することができない場合もある.
つまり,初めから完全な設計はできないということを肝に銘じておくことである.抽象インターフェースを包含した設計は,デザインパターンにも頻出する形である.
図1 理想のクラス図
4 おわりに
今回のレポートは,難易度が高かったと思う.よって次回は,クラスについての紹介をしたいと思う.以上で,設計の原則を終了する.
参考資料
[1] 著:ロバート・C・マーチン(2008)「アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の真髄と匠の技」 SoftBankCreative 682pp.
最終更新:2008年07月13日 15:16