2011年8月20日土曜日

JavaScriptでObserverパターンを書いてみた

Observerパターンのサンプルはこちら
http://jsdo.it/windblue/y87e

サンプルの概要としては、
  • 「左のボタン」と「右のボタン」がある
  • 「左のボタン」を押すと、「左のボタン」が大きくなり、「右のボタン」は元の大きさに戻る
  • 「右のボタン」を押すと、「右のボタン」が大きくなり、「左のボタン」は元の大きさに戻る

中規模程度のDHTMLで且つ、ある要素で発生したonclickなどのイベントが他の要素に影響を与えるような場合に使えるのではと思います。
逆に言えばごく簡単なDHTMLには冗長な記述だし、大規模なDHTMLとしてはStateパターンなどを組み合わせるなどしないとつらいと思います。

Observerパターンとは
Observerパターン - Wikipediaを参照してください(手抜き)。

これでif文地獄から抜け出せる
ストレートに書くなら、
if(左のボタンを押されたとき){ doSomething(); }


if(右のボタンを押されたとき){ doSomething(); }

のようなコードになりがちですが、中規模以上のWebアプリなどになると、これではif文地獄になってえらいコトになると思います。

それを避けるために、サンプルでは画面上の要素たちを各モデルに分解して、それぞれのモデル(「左のボタン」モデルと「右のボタン」モデル)に、「左のボタン」を押されたときの挙動、「右のボタン」が押されたときの挙動、を記述していきます。

サンプルコードの簡単な説明
http://jsdo.it/windblue/y87eのソースにもちょこちょこコメントを書いていますが。

各モデルに対し、イベントハンドラを登録。
たとえば、「左のボタン」モデルに対しては「左のボタン」のonclickのイベントハンドラを登録。
そのイベントハンドラが、コントローラの「左のボタン」が押されたよメソッドを呼ぶ。
すると、コントローラは「左のボタン」モデルと「右のボタン」モデルの、「左のボタン」が押されたよメソッドを順番に呼んでいきます。
この順番に呼ぶ部分がObserverパターンです。
で、それぞれのメソッドが全て呼ばれたら、表示を変更するために、コントローラが「左のボタン」モデルと「右のボタン」モデルのonUpdateメソッドを呼んでいきます。

また、各モデルは大本となるモデルクラスを継承しています。
モデルクラスは、コントローラから呼ばれる各モデルのメソッドを全て定義しています。
Javaでいうinterfaceのような役割を持っています。
サンプルでは全て空のfunctionです。
「このモデルではこのメソッドがコントローラから呼ばれても特に何もさせない」という場合、そのモデルではそのメソッドを定義していません。
すると、大本のモデルクラスの空メソッドがコントローラから呼ばれるコトになります(interfaceというよりはabstractって感じですね)。
これにより、
コントローラ「このモデルにメソッドが定義されていないじゃないか!(怒)」
というコトが避けられます。

以上になります。

あと全然関係ないけど
Operaだとなぜかjs do.itのタイトルが編集できませんでした。
なんで!(怒)

Related Posts Plugin for WordPress, Blogger...