コンポジション
機能を定義する細かい部品をくっつけてオブジェクトを構成する手法を「オブジェクトコンポジション」と言います。この場合、もともと複数の部品をくっつけることが前提ですから、たくさんの部品を一度にくっつけても問題は起きないのです。
コンポジションに関する誤解
全体クラスと部分クラスのインスタンスのライフサイクルは一緒 ×
部分インスタンスは全体インスタンスに関わらず追加・削除できる。
全体インスタンスを乗り換えることで、部分インスタンスだけ生き残ることが出来る。
全体インスタンスを乗り換えることで、部分インスタンスだけ生き残ることが出来る。
全体側の多重度は1 ×
正しくは、
全体側の多重度はたかだか1 ○
部分インスタンスは全体に組み込まれていなくても存在できる。
部分クラスが複数の全体クラスにコンポジションで結ばれることはない ×
クラス図で複数の全体クラスに結ばれる場合、
オブジェクト図では、それぞれ別の木構造になる
オブジェクト図では、それぞれ別の木構造になる
継承よりもコンポジション
コンポジションは柔軟性が高く、カプセル化が強いのに対し、継承は柔軟性に劣り、カプセル化も弱いのです。(UMLによるJavaオブジェクト設計)
継承を使う場合
- クラス間に「is-a」関係が成立する場合にのみ継承を用いる
- コードの再利用だけが目的ならば継承は使わない
- ポリモリフィズムの実現には、継承よりもコンポジションとインタフェースの組み合せのほうが有効である
Matz氏曰く
継承を使いたくなるケースでは、明示的な委譲の定義が繁雑で、「こんなこと自分でしなくちゃいけないのは変だ」と感じます。
私個人が継承を用いるかどうかについての唯一絶対のルールは「is-aの関係にあるか」です。この関係が成立しない時に継承を使うのは純粋に間違いです。
コンポジションの一般例
- (継承における)親クラスのオブジェクトをprivate変数に取り込む(インスタンス化する)
コンポジションのデメリット
- 親クラスの必要なメソッドは、適宜再定義する必要がある
AS3でのコンポジション推奨
コンポジションには実行時に他のクラスに機能を追加できるという利点があります。コンポジションはクラスインスタンスの作成および廃棄を制御します。継承ではクラスの関係はコードがコンパイルされる際に、固定され定義されます。
個人的体験
- 継承は、親クラスのメソッドの引数やらaccess specifierやらを熟知してないとコンパイルエラーになる。めんどい
- 多重継承よりもコンポジション(AS3は多重継承ができないので、必然的にコンポジション多用するようになった)