インターフェイス
2009/01/29 20:35 - AS3.0
今までデザインパターンの学習中に何度か「インターフェース」に触れることがありましたが、その意義が今ひとつよくわかりませんでした。 まぁ腰をすえて調べてみようとも思いませんでしたが。
インターフェイスとはいったい何か。
対象クラスに備えなくてはならないメソッドを強制的に実装させるための雛形といったところでしょうか。
Iterator パターンを自習したときのこと。 インターフェイスを implements すべきとされていたクラス群は、どのクラスもインターフェイスで定義されたメソッドは、同じコードになっていました。
コードが同じになるんなら、インターフェイスのコードの方でメソッド内コードが定義できた方が楽なのになぁ、とそのときは考えました。
メソッド名と引数が指定できるだけで、メソッドの中身はコーディングできないその機能に、どれだけのパワーが秘められているのか実感できなかったんです。
しかし先般の Observer パターンのオブザーバークラス群を見て「あ、インターフェイスって便利かも。むしろメソッドの中身が指定できないからこそ意味があるのだな」と、反省する次第。
まずメソッドの中身を定義しないことの意義。
以前の Observer パターンのときに提示したコードの再掲ですが、上が DisplayObserver、下が KillObserver です。 インターフェイスで定義された update メソッドですが、その中身はまったく違います。
もしインターフェイスでメソッドの中身まで定義しなければいけないなら、このような柔軟性は得られるべくもない。
次はクラスの型っぽい扱いができることの意義。
これまた再掲コードですが、オブザーバークラス群を呼び出す側のクラス Input.as のオブザーバークラス群との接点に関わるコードを見てみます。
addObserver メソッドの引数の型、notifyObservers の for each ループで取り出される element の型、いずれも IObserver インターフェイスが指定されています。
もし仮にインターフェイスがない場合、Observer クラスのような抽象クラスを作って、その Observer クラスを継承して DisplayObserver と KillObserver を作るという手段をとらざるを得ない。
しかし!
オブザーバークラスになる側のクラス、DisplayObserver と KillObserber について見てみましょう。
DisplayObserver は TextField クラスのサブクラス、KillObserber はいずれのサブクラスでもないクラスです。
ActionScript では多重継承はできません。 ということは TextField クラスのサブクラスである DisplayObserver クラスは、Observer クラスのサブクラスとして設計できないということです。
ってこたぁ addObserver(observer:Observer) みたいなことができないし、notifyObservers 内で for each(var element:Observer in aryObserver) ということもできない。
しかし Input.as の addObserver メソッドの引数の型、notifyObservers の for each ループで取り出される element の型にクラスではなくインターフェイスを指定することで、まったく起源の異なる DisplayObserver と KillObserver を同一に扱うことができる。
なんか、とってもすばらしいことなんじゃないでしょうか。
何を当たり前のことを言っているんだ、と思われる方々もおられるかも知れませんが、知識の乏しいローテクプログラマーとしては、この事実に触れて「ユリイカ!」と叫びたい気分になったのでした。