SWTやEclipseプラグインのイベントドリブンの仕組みについてしらべてみました。
イベントとは †
そのまえに一般的に、GUIプログラミングにおける「イベント」とは、
- マウスでクリックされた
- 値が変わった
- ウィンドウがCloseされた
などの「状態の変化」のことで、「イベント駆動型」の処理とはその変化が起こったときに何か「処理」をするための仕組みをいいます。
たとえば †
上の例だと
- マウスでクリックしたときに、ダイアログを出す
- 値が変わったときに、値チェックをする
- ウィンドウがCloseされたときに、いろいろなりソースを解放する
などがそのイベント駆動型の処理にあたります。
オブザーバパターン †
で、そのイベント駆動型(イベントドリブン)の処理を実現する方法は、すでにイディオムが確立されています。実現するには、デザインパタンでいうところのいわゆる「オブザーバパタン」を使用します。
オブザーバパターンとは
- ある状態を監視するObserver <- ダイアログを出すヤツ
- ある状態を監視されているSubject <- マウスでクリックされるヤツ
があり「Subjectの状態が変化するとObserverのあるメソッドを呼ぶ」という仕組みです。
正確にはObserver(s)はあらかじめSubjectに「なんかあったら通知してね」とお願いをしておき、Subjectは「何かあったからObserverたちに通知するよ」という仕組みとなります。
もっと正確には、Observer(s)はあらかじめSubjectに自分を登録(たとえばaddObserverとか言うメソッド名)しておいて、Subject側はしかるべき時に、Observer(s)の決められたメソッド(interfaceのメソッドになる)を呼ぶ、という仕組みになります。
ポイントは
- Observerは監視しつつ何かあったら起動するようなことをいってるが、実際は登録しておいてSujectに自分のメソッドを呼んでもらってる
- Subjectは最初に登録されるものの、どの様なObserverが登録されてるかはあまり気にしない*1
- つまり何かあったら登録してる奴ら全員に通知する、みたいな動きをする
- こうすることで、たとえば「時計ロジック(Subject)」「アナログ時計描画クラス(Observer)」「デジタル時計描画クラス(Observer)」はそれぞれのアルゴリズムを意識しなくてもそれぞれの責務に専念できる
といったところです。
さて上でメソッド名やinterfaceなどが出てきましたが、まとめると以下のようになります。
- SubjectはObserverを登録するためのメソッドaddObserverをもつ
- Subjectは一般的にフィールドにObserverをListなどで保持しておく
- ObserverはSubjectに起動される共通のメソッドをもつ、つまりObserver InterfaceはmouseClicked()などが宣言される
- Subject側はしかるべき時に、フィールドのObserverのListからObserverを取り出し、すべてのObserverのmouseClicked()を呼ぶ
イベントドリブンの処理を実装する †
ところで、いわゆるイベントドリブンの実装をするときはObserverはListenerと呼ばれます。
先の話をListenerに置換して繰り返すと
- SubjectはListenerを登録するメソッドSubject#addHogeListener?(HogeLister? listener);をもつ
- Subjectは一般的にフィールドにListener(s)をListなどで保持しておく
- Listenerインターフェースを実装するクラスは、Subjectに起動してもらうためのメソッド、たとえばmouseClicked(Event e)などを実装する
- Subjectはしかるべき時に、フィールドのListenerのListからListenerを取り出し、すべてのListenerのmouseClicked(Event e)を呼ぶ
となります。なんとなく処理が見えてきましたね。
イベントクラス †
SWTでのイベント †
この記事は
- Eclipseの話にはいれねー、じかんがねー -- きの?
現在のアクセス:14675