イベントクラスを定義する

March 19, 2006category: Flash 

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

comments (0)このエントリーを含むはてなブックマークはてなブックマーク - イベントクラスを定義する

comments