継承よりもコンポジション(2)
2009/02/01 18:37 - AS3.0
クラス拡張の手段は「継承」の他に「コンポジション」というテクニックもあるということを知り、またひとつ賢くなった、みんな「詳説 ActionScript 3.0」読もうぜという話の続き。
しっかし私この「コンポジション」という言葉初めて聞きましたよ。 しかも「詳説 ActionScript 3.0」のP130には「継承よりもコンポジションの方が重要だ」と書いてあるじゃあないですか。
曰く「アプリケーションデザインの戦略としてコンポジションの方が継承よりも好まれることが多い」
曰く「有名なオブジェクト指向デザインの理論家の中にも明らかに継承よりコンポジションを指示する人々がいる」
曰く「継承が明らかに適切と思えるようなときでもコンポジションを考慮に入れることが勧められている」
そんな重要なテクだというコンポジション。 今まで何冊かオブジェクト指向の本読んできたけど一度も目にしたことなかったぞ。一体どうなってんの。
そんなオレ的新機軸なコンポジションですが、具体的にどんなものかというと、コードを組むときにはごく当たり前に使っている何の変哲もない手法でした。
あるクラス(以下フロントエンドクラス)がその内部で別のクラス(以下バックエンドクラス)のインスタンスを呼び出して、それをプロパティとして保持します。 そしてフロントエンドクラスはそのメソッド内でバックエンドクラスインスタンスを適宜呼び出し処理を委譲する、というのがコンポジションです。
Sprite.graphics とか Shape.transform.matrix とかまさにソレですよね?
しかもこの手法、デザインパターンの本読んでるときに頻出してましたよ。コンポジションという名前は一度も見ませんでしたが。
こんな当たり前過ぎる手法に「コンポジション」なんていう仰々しい名前が付けられていたとは…… しかもオブジェクト指向的には重要なテクニックだったとは…… 今更ながら自分の無知に愕然とする次第。
今まで何冊かオブジェクト指向の本読んできたけれどそんな話(以下同文)。
新たな知識を得た今、オーバーライドで失敗していた私は、さっそく継承ではなくコンポジションでクラス設計をやり直しました。
その結果以下の三つ(プラス1)のクラスができました。
Pixelizer がバックエンドで BitmapData 走査が機能です。
ImagePixelizer と TextPixelizer がそれぞれフロントエンドになり、BitmapData を Pixelizer に送り、走査結果を受け取ります。
これらはスキャンに時間がかかることを考えてイベント駆動にしているため PixelizerEvent クラスも作ってあります。
実際コード組んでみると、バックエンドと各フロントエンドの関係は美しく決まっているんだけど、ImagePixelizer と TextPixelizer のコードがかなりカブっていてあまり効率的とは言えない。
でも継承を使うよりははるかにキッチリまとまっているのでコンポジションで推し進めます。
続く。