Observer パターン(後編)
2009/01/27 20:20 - デザインパターン
今回はサンプルでもって Observer パターンの挙動を細かく見てみます。
いきなりサンプルから。
これは、入力欄に文字列を打ち込んでボタンをを押すと、入力した内容が表示され、入力欄は消える、というものです。 1回に限り文字列の入力を許す仕掛けと思ってください。
このサンプルは以下のクラスから成り立っています(ZIP ファイル)。
- Main.as (ドキュメントクラス)
- Input.as (入力欄)
- Button.as (入力欄のボタン)
- DisplayObserver.as (表示担当のオブザーバー)
- KillObserver.as (入力欄抹消担当のオブザーバー)
- IObserver.as (オブザーバーのインターフェイス)
前回、模式的に説明した内容だと、オブジェクトAに該当するのが Input クラス、オブジェクトB、Cに該当するのが DisplayObserver クラスと KillObserver クラスです。
ということは Input クラスにはオブザーバーへの発信のしくみが、二つのオブザーバークラスには Input クラスからの受信のしくみが付いているわけです。
まずは Input クラスの発信の機構から。
発信の機能は一つのメンバプロパティと二つのメソッドで構成されています。
オブザーバーを格納する配列 aryObserver と、その配列にオブザーバーを登録する addObserver メソッド、そして配列内の各オブザーバーに通知をする notifyObservers メソッドです。
このサンプルではインプットボタンが押されたときが各オブザーバーへの通知のタイミングです。 よって、notifyObservers はInput.as 内の MouseEvent.CLICK のハンドラで呼び出されます(Input.as の当該コード参照)。
そしてそれよりも前に、あらかじめ addObserver で呼び出しをかける全てのオブザーバーを登録しておく必要があるわけです(Main.as の当該コード参照)。
次は受信の機能。 Input.as の notifyObservers を見ていただくと分かるとおり、全てのオブザーバーの update メソッドが呼び出されます。
で、各オブザーバーの update メソッドにはそれぞれ自分のおこなうべきことが個別にコーディングされている、というわけですね。
上が DisplayObserver、下が KillObserver です。メソッド名は同じ updata、引数も同じInput タイプのものなのに、その処理内容はまったく違うことがお分かりかと思います。 これぞポリモーフィズムの賜物。
DisplayObserver は TextField のサブクラスになっています。 自らの text プロパティに Input オブジェクトの入力欄に入力された文字列を代入します。 結果としてステージ上に Input オブジェクトに入力された文字列が表示されることになります。
KillObserver は Input オブジェクトに null を代入します。 Input オブジェクトはボタンが押されたときに自らを removeChild しますが、KillObserver がとどめを刺すわけです。 Input.as には自分に null を代入する記述はできないから、誰か他の人(この例では KillObserver)に介錯をしてもらうと、まぁこういうこと。
このサンプルの場合だと、KillObserver は別に必要ないような気がしないでもないけれど、まぁケーススタディということで。
で、オブザーバークラスは IObserver.as というインターフェイスを implements しておく必要があるわけですね。
IObserver.as は超短いです、たったこんだけ。
でもこれがキモになるわけです。 今までインターフェイスってあんまよく分からなかったんですが、今回の事例で初めてその意義が理解できました。