- - PR -
複数のリスナーを登録してイベントを発生させたい
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2008-12-21 21:30
あなたがやろうとしていることが良く分かりません。クラスの名前が EventManager となっていますが、これは何です? Foo1Occurred イベント、Foo2Occurred2 イベントを持つイベントソースではないのですかね? それとも他のイベントソースの実装を代理するような存在としてクラスを設計しているのでしょうか?
まず、あなたの書いている上記のコードが私には理解できません。イベントとは何かの操作や変化に対して発生するものですから、fire メソッドを外部から呼び出すという上記のコード自体が、イベント設計として何か勘違いしているのではないかという印象を受けます。 あなたが最初に提示したコードでは fire メソッドは protected になっていますよね? これはイベント設計としては適切なアクセス範囲だと私は思っています。あなたは、なぜ、fire メソッドを protected にしたのですか? そして、なぜ、ここで em.fire〜 という外部からイベント発行を呼び出すコードを提示されたのですか? EventManager クラスとは何ですか? イベントを管理するクラスが何のために必要になりましたか? 通常は、それぞれのクラス(イベントソースとなるオブジェクト)について、イベントを実装(add/remove/get/fire)すれば済みます。そうではなくて、イベント関連メソッド(add/remove/get/fire)を、他のクラス(EventManager) に委譲するような設計を考えているのでしょうか? | ||||||||
|
投稿日時: 2008-12-22 10:09
taziさんが悩んでいるところって、
イベントを通知する側のクラスがいくつもあるのだが、それぞれのクラスで個別に リスナのリストを管理すると、個々の通知側のクラスにコードが分散してしまう。 そこで、まとめて扱うためのEventManagerを導入しようと考えたのだが、 複数の種類のイベントを扱おうとしたときに、どう設計したらよいか わからなくなった、というところなのではないですか? そうだとすると、 java.beans.PropertyChangeSupportの考え方が参考になると思います。 これはリスナのリスト管理とリスト中のリスナへのイベント発火を行うクラスで、 taziさんのEventManagerと似ていますが、対象はPropertyChangeEventのみです。 ひとつのクラスで全ての種類のイベントに対応しようとすると 対応したいイベントの種類が増える度に際限なく肥大化していきますが、 個々のサポートクラスの責任範囲をひとつのイベントの種類に限定すれば、 サポートクラスの数は増えますが、個々のクラスはシンプルなままです。 | ||||||||
|
投稿日時: 2008-12-27 19:40
返答が遅くなり申し訳ございません。
EventManager クラスの役割についてですが、あしゅさんがフォローして頂いた通りです。 現在書いているプログラムはそれほど大規模なものではないため、EventManager クラスに全てのイベントを管理させる形で特に問題なく実装できました。 ただし、今後のためにもう少し勉強したいと思います。 皆さん色々とアドバイスありがとうございました。 | ||||||||
|
投稿日時: 2008-12-28 17:46
みなさまこんにちは。
以下はとくにどなたへのコメントというわけではなく、私のメモ書きだと思って見ていただければと思います。 こういうイベントマネージャーのような仕組みは、(Java ではないですが)たとえば Windows 3.0 や 2.0 の時代からも SendMessage をしてそれを WndProc(HWND, UINT, WPARAM, LPARAM) のような仕組みで受けていました。このキューに溜まるメッセージはさまざまな種類のメッセージのごった煮状態であり、使用言語はオブジェクト指向言語に限定するわけではありませんが、受け取った側でダウンキャスト(や instanceof などでの判定)に相当することをやることは必要でした。 そして、こういうイベントマネージャーはだれが作ってもこれと似たような仕組みになってしまうものだと思います。 この理由は、結局は、キーやマウスといった種類の違うメッセージをひとつのキューに入れるからであり、仕方がないことだと思います。そしてなぜキューを種類ごとに分けずにひとつにするのかというと、種類数の数だけ爆発的に増えるのを避けることと、また、もうひとつの理由としては時系列で管理したいから、ということもあるかなと思います。 私は、種類の数がそれほど増えないのならば、キューは種類の数だけ分けるのもアリかなと思います。時系列の管理がややこしくはなりますが、それほど難しくはないでしょう。 | ||||||||
|
投稿日時: 2009-01-09 17:02
去年のネタですが、面白そうなのでジェネリクスを使って書いてみた。
以下がtazi氏のEventManager相当のクラス。
以下がそれを使うクラス。
EventListenerListを扱う処理がEventMulitcasterクラス内に隠ぺいされました。 個々のイベントソースでEventListenerListを直接扱わずに済むので、 ちょっとは利用価値があるのかな。 メソッド呼び出しにいちいち型トークン(Hoge.class)を指定するのが面倒ですが。 注意 (追記) 上記のEventMulticasterではイベントオブジェクトをすべての配信先リスナで共有しています。安全に共有するためにはイベントオブジェクトは不変オブジェクトであるべきです。 EventMulticasterは独自のIEvent型を使用していますが、それをjava.awt.AWTEventなどに変える場合は、AWTEventは不変でないのでEventDispatcherのdispatchメソッドの内部でイベントを生成する必要があるでしょう。EventListenerListのドキュメントも参考にしてください。 [ メッセージ編集済み 編集者: sawat 編集日時 2009-01-09 17:45 ] |