第8章 視野を広げる
オブジェクト
- オブジェクトはデータとメソッドを持ったものという考え方は実装レベルでしかものを考えられていない。
- 概念レベルで考えると、オブジェクトは、責務を備えたものと考えることができる。
- この時、どのような実装にするかという詳細部分を検討することなく、オブジェクト自身が行うべきことが何なのかということを定義するところから始めることが出来る。
- つまり、人間というオブジェクトが歩くには右足を前に出してその後左足を前に出して、などと言った詳細な手順を気にすること無く、人間というオブジェクトには歩く、話す、という責務がある、というオブジェクトとしての責務から考えることができ、その詳細を隠蔽し、人間へ命令をする側は、歩く、話すといった振る舞いの内部の処理を一切気にしなくて良くなる。
カプセル化
- カプセル化はオブジェクトの持つデータの隠蔽のことだけを指すわけではない。
- その他に以下の要素も隠蔽する。
- 実装:概念レベルで定められたオブジェクトの振る舞いが実際にどのように実現されているか。
- 派生クラス:実際にオブジェクトがどのクラスに属しているか。
- 設計詳細:どのような機能がありどのように呼び出されるか。
- 実体化規則:実体化する際にどのような初期化がなされるか。
- カプセル化は流動的要素による影響(仕様変更の影響)をオブジェクト内に閉じ込める効果(結合度を低下させる効果)がある。
クラス設計に関する誤解
- 派生クラスによって振る舞いが更に派生するような場合、派生クラスごとにその振る舞いをそれぞれで実装するのはやめたほうが良い。
- 例えば動物オブジェクトに移動するという責務がある場合。ライオンなら4足歩行、鳥なら飛行、人間なら2足歩行、魚なら泳ぐ、といった具合である。
- このような場合は振る舞いそのものを抽象クラスによって隠蔽してしまえばよい。
- 動物オブジェクトの例だと、移動手段クラス(抽象クラス)を定義してやり(4足歩行クラス、飛行クラスなどを派生させる)、それを動物クラスのデータメンバとして保持させるとよい。
- この方法は、単なるデータメンバ(脚の本数のような)と本質的に大差はない。違うのは数値ではなく振る舞いを表現しているという点だけである。
- 動物オブジェクトの例だと、移動手段クラス(抽象クラス)を定義してやり(4足歩行クラス、飛行クラスなどを派生させる)、それを動物クラスのデータメンバとして保持させるとよい。
- あるオブジェクトが他のオブジェクトを保持するのとあるオブジェクトが単なるデータメンバを保持するのは全く違うことのように見えるが実際は同じことである。
- 属性情報の流動的要素を保持するのも、振る舞いの流動要素を保持する(先程の移動手段の例)のも同じようなことと考えることができ、そのようにすることでクラスが複雑化し、結合度が上がることも防げる。