EventDispatcher.dispatchEvent() で発行するイベントオブジェクトのクラスを定義すると、より厳密なイベントの管理が可能になる。
例えば、「車が走った」というイベントを考える。この場合、イベントオブジェクトのイベントソースは車で、イベントタイプは "onMove" となる。また、属性として、イベントが発生した瞬間の位置情報 (x,y) を持たせる。まず、従来の Object 型を使ったパターンを見てみる。
Object 型のイベントオブジェクトを使用したパターン
車クラスの move() メソッドでイベントを発行する。target 属性は省略が可能 (EventDispatcher が割り当ててくれる)。
class Car extends EventDispatcher { //コンストラクタなど /** * 移動する */ public function move():Void { //イベントを発行する var event:Object = new Object(); event.type = "onMove"; event.x = this.x; event.y = this.y; this.dispatchEvent(event); } }
クライアントは車の移動イベントをリスンする。
private function myCarMove(event:Object):Void { trace([event.x, event.y] + "から移動した"); } this.myCar.addEventListener("onMove", Delegate.create(this, myCarMove));
このパターンを、イベントクラスを用いたものに変更する。まず、基底クラスとなる Event クラスを定義する。
Event クラス
class Event { public var target:Object; public var type:String; /** * コンストラクタ * @param type イベントタイプ */ public function Event(type:String) { this.type = type; } }
EventDispatcher が書き換えるフィールド (target と type) は public にする。
次に、この Event クラスを継承した MoveEvent クラスを定義する。
MoveEvent クラス
class MoveEvent extends Event { public static var MOVE:String = "onMove"; private var x:Number; private var y:Number; /** * コンストラクタ * @param x x座標 * @param y y座標 */ public function MoveEvent(x:Number, y:Number) { super(MoveEvent.MOVE); this.x = x; this.y = y; } /** * x座標を得る * @return x座標 */ public function getX():Number { return this.x; } /** * y座標を得る * @return y座標 */ public function getY():Number { return this.y; } }
位置情報をコンストラクタで与えている。イベントタイプを定数 MoveEvent.MOVE にして、リスナを作成する際には "onMove" という文字列ではなく、MoveEvent.MOVE を指定する。
では、先ほどの車の例を、このクラスを用いたものに書き換えてみる。
MoveEvent 型のイベントオブジェクトを使用したパターン
車クラスの move() メソッドでイベントを発行する。
class Car extends EventDispatcher { //コンストラクタなど /** * 移動する */ public function move():Void { //イベントを発行する var event:MoveEvent = new MoveEvent(this.x, this.y); this.dispatchEvent(event); } }
クライアントは車の移動イベントをリスンする。
private function myCarMove(event:MoveEvent):Void { trace([event.getX(), event.getY()] + "から移動した"); } this.myCar.addEventListener(MoveEvent.MOVE, Delegate.create(this, myCarMove));
いくつかのハードコードしていた文字列が無くなり、Object 型のイベントオブジェクトを使用したパターンよりも、すっきりしたコードになる。また、イベントオブジェクトがカプセル化され、より安全な設計になったと言える。
今回のイベントクラスの設計は、ActionScript 3.0 のイベントパッケージを参考にした。