LoginSignup
22
23

More than 5 years have passed since last update.

javascriptでEventDispatcherを使うときのメモ

Posted at

なぜ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のインスタンスを知る必要はなく、依存関係を取り除くことができる。

22
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
23