拡張オブジェクトパターンの本質

以下のブログエントリで,Eclipseで重要な役割を担っている,拡張オブジェクトパターンについて紹介しました。

結局のところ,拡張オブジェクトパターンの本質は,継承ではなくコンポジションを利用した設計をしていること,だと思います。

継承ではなくコンポジションを利用した設計については,多くの書籍で議論されています。一言でまとめると,クラスの機能や責務を拡張する場合,ほとんどの場合,継承よりコンポジションが適切であるということです。継承を使うと,親クラスに対して子クラスが深く依存してしまいます。

以下の書籍の2章のタイトルは「継承ではなくコンポジションを利用した設計」。拡張オブジェクトパターンは,まさにこの書籍が示す指針を巧妙に具現化したものと言えます。拡張オブジェクトパターンでは,あるクラスの機能を拡張したい場合,新しいクラス(アダプタ)をコンポジションとして付け加えます。

UMLによるJavaオブジェクト設計

UMLによるJavaオブジェクト設計

  • 作者: ピーターコード,マークメイフィールド,Peter Coad,Mark Mayfield,依田光江,依田智夫,今野睦
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/01
  • メディア: 単行本
  • クリック: 11回
  • この商品を含むブログ (12件) を見る

一方,名書「Effective Java」の項目14のタイトルは「継承よりコンポジションを選ぶ」。一見,上記と同じ議論がされているようなタイトルですが,そうではありません。この章では,継承を利用してもよさそうなケース(「親クラスの特別な種類を作りたい」とか)を議論しています。ですから,継承ではなくラッパーまたはデコレータパターンを推奨する,という結論になっています。したがって,拡張オブジェクトパターンとは直接関係ないことになります。拡張オブジェクトパターンは,まったく新しい機能/責務を追加する場合に利用するものです(例えば,ドメインモデルにUIを付け加えるとか)。

Effective Java プログラミング言語ガイド

Effective Java プログラミング言語ガイド

以上をまとめると,継承を使う代わりに

  • 既存のクラスに全く新しい機能/責務を追加する場合には,拡張オブジェクトパターンが良い
  • 既存のクラスの特別な種類を作る場合には,ラッパーまたはデコレータパターンが良い