キレイなイベントの回し方
ここのところ、オーダーメイドなカスタマイズでオラオラ回してた訳です。
でも、再利用性が低い問題がありました。
そこで設定で何でも出来ればいいということで、もしもし文を沢山書いた訳です。そして、マクロが嫌いになりました。
さて、そこでオブジェクト指向による多態性を使いたい。
継承だけでなんとかしたい。しかしうまくいかない。むぅ。
そこで、イベントリスナーなインターフェイスです。でも、いちいち使わないイベントリスナーは登録したくない。
しかも、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();