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 のイベントパッケージを参考にした。