キレイなイベントの回し方

ここのところ、オーダーメイドなカスタマイズでオラオラ回してた訳です。
でも、再利用性が低い問題がありました。
そこで設定で何でも出来ればいいということで、もしもし文を沢山書いた訳です。そして、マクロが嫌いになりました。
さて、そこでオブジェクト指向による多態性を使いたい。
継承だけでなんとかしたい。しかしうまくいかない。むぅ。
そこで、イベントリスナーなインターフェイスです。でも、いちいち使わないイベントリスナーは登録したくない。
しかも、1個しか登録出来ないのは困る。
これはデザインパターンでいうところのオブザーバーパターンです。でも、オブザーバーパターンはJavaアプレットのトラウマでみんな嫌いです。
C#のイベントです。ActionScriptのaddEventListenerとdispatchEventです。
でも今度は、イベントが別な意味で使われる事が多くなってしまいました。むぅー。
プラグインっていう名前も使われている。
困った世の中です。
ということで、只のリスナーを追加し、リスナー達に通知することにしました。
これでばっちり。リスナー登録しておいて、リスナーに通知するだけです。
もう、リスナーにわざわざ来てもらう事もありません。
リスナーでかぶって困るのはラジオ局くらいです。ラジオ局のリスナー達のイベントに行ってみたいと思ったのはラジアメが最後です。俺的に大丈夫です。
もしもし文もいりません。バンザイ!
さぁ、こんなかんじで、みんな早く帰って寝ようぜ。

<?php
class Event {
  var $conf = array(
    "has_raid"=>true,
    "has_item"=>true,
    //"has_door"=>true,
  );
  function __construct() {
    $this->load_listener("has_door");
    $this->load_listener("has_raid");
    $this->load_listener("has_item");
  }
  function load_listener($conf) {
    $confs = explode("_",$conf);
    if (isset($this->conf[$conf])) $this->$confs[1] = new $confs[1]($this);
  }
  var $listeners = array();
  function add_listener($name, $handler) {
    if(!isset($this->listeners[$name])) $this->listeners[$name] = array();
    $this->listeners[$name][] = $handler;
  }
  function notify_listeners($name, &$data) {
    $args = array(&$data)+array_slice(func_get_args(),2);
    foreach ($this->listeners[$name] as $listener) {
      call_user_func_array($listener, $args);
    }
  }
}
class Quest {
  function exec() {
    $event = new Event();
    $data = array();
    $event->notify_listeners("on_quest_exec", $data);
    $event->notify_listeners("on_quest_exec2", $data);
    var_dump($data);
  }
}
class Raid {
  function __construct($event) {
    $event->add_listener("on_quest_exec", function(&$data){$data["raid"]=1;});
  }
}
class Item {
  function __construct($event) {
    $event->add_listener("on_quest_exec", function(&$data){$data["item"]=1;});
    $event->add_listener("on_quest_exec2", array($this, "on_quest_exec2"));
  }
  function on_quest_exec2(&$data){
    $data["item"]=2;
  }
}
class Door {
  function __construct($event) {
    $event->add_listener("on_quest_exec", function(&$data){$data["door"]=3;});
  }
}
$quest = new Quest();
$quest->exec();