javascriptでEventDispatcherを使うときのメモ

More than 5 years have passed since last update.


なぜEventDispatcherが必要なのか

例えば以下のような関数を定義した場合。


sample.js

var global = {}

(function() {
function class1() {
function method1() {
}

return {
method1: method1
}
}

global.class1 = class1;
})();

(function() {
function class2() {
// class2で発火するなにかしらのEventに対してclass1のmethod1を実行したい
}

global.class2 = class2;
})();

(function() {
function class3() {
var instance1 = new global.class1,
instance2 = new global.class2;
}
})();


class2の中でclass1のmethod1を実行したい場合。

普通に考えるとclass2はclass1のインスタンスにアクセスできなければいけないが、class1のインスタンスはclass3しか持っていない。


EventDispatcherを使わない場合

EventDispatcherを使わずに実現させようとするとおそらく下記の様になると思う。(他にも方法はいくらでもあると思うけど)


not_event_dispatcher.js

var global = {}

(function() {
function class1() {
function method1() {
}

return {
method1: method1
}
}

global.class1 = class1;
})();

(function() {
function class2(instance1) {
// class2で発火するなにかしらのEventに対してclass1のmethod1を実行したい
function clickEvent() {
instance1.method1();
}
}

global.class2 = class2;
})();

(function() {
function class3() {
var instance1 = new global.class1,
instance2 = new global.class2(instance1); // instance1を引数で渡す
}
})()


こうすることで確かに実行は可能だが、class3で定義したinstance1を他のクラスでも使いまわすと、依存関係が強くなってしまいあまり好ましくない。


EventDispatcherを使うと

EventDispatcherを使うことでこの依存関係を取り除くことができる。

次の例は、class1, class2, class3はすべてEventDispathcerを継承し、そのインターフェースを持っているものとする。


use_event_dispatcher.js

var global = {}

(function() {
function class1() {
function method1() {
}

return {
method1: method1
}
}

global.class1 = class1;
})();

(function() {
class2.prototype.EVENT1 = 'EVENT1';

function class2(instance1) {
var self = this;

// class2で発火するなにかしらのEventに対してclass1のmethod1を実行したい
function clickEvent() {
// この時点で、class1のインスタンスを知っている必要はなく
// あくまでもEVENT1が発火されたことだけをEventDispathcerに伝える。
self.dispatchEvent(self.EVENT1);
}
}

global.class2 = class2;
})();

(function() {
function class3() {
var instance1 = new global.class1,
instance2 = new global.class2;

// instance2のEVENT1というイベントに対して関数を追加する
instance2.addEventListener(instance2.EVENT1, function() {
instance1.method1();
});
}
})()


上記の様にすれば、class2はclass1のインスタンスを知る必要はなく、依存関係を取り除くことができる。