观察者模式

也称为‘订阅/发布模式’。

通过创建‘可观察对象’,当发生一个感兴趣的事件时,可以将该事件通知给所有观察者,从而实现松耦合。

http://www.jspatterns.com/book/7/observer.html

  var publisher = {
        subscribers: {
            any: [] // event type: subscribers
        },
        subscribe: function (fn, type) {
            type = type || 'any';
            if (typeof this.subscribers[type] === "undefined") {
                this.subscribers[type] = [];
            }
            this.subscribers[type].push(fn);
        },
        unsubscribe: function (fn, type) {
            this.visitSubscribers('unsubscribe', fn, type);
        },
        publish: function (publication, type) {
            this.visitSubscribers('publish', publication, type);
        },
        visitSubscribers: function (action, arg, type) {
            var pubtype = type || 'any',
                    subscribers = this.subscribers[pubtype],
                    i,
                    max = subscribers.length;

            for (i = 0; i < max; i += 1) {
                if (action === 'publish') {
                    subscribers[i](arg);
                } else {
                    if (subscribers[i] === arg) {
                        subscribers.splice(i, 1);
                    }
                }
            }
        }
    };

    function makePublisher(o) {
        var i;
        for (i in publisher) {
            if (publisher.hasOwnProperty(i) && typeof publisher[i] === "function") {
                o[i] = publisher[i];
            }
        }
        o.subscribers = {any: []};
    }

    var paper = {
        daily: function () {
            this.publish("big news today");
        },
        monthly: function () {
            this.publish("interesting analysis", "monthly");
        }
    };

    makePublisher(paper);

    var joe = {
        drinkCoffee: function (paper) {
            console.log('Just read ' + paper);
        },
        sundayPreNap: function (monthly) {
            console.log('About to fall asleep reading this ' + monthly);
        }
    };

    paper.subscribe(joe.drinkCoffee);
    paper.subscribe(joe.sundayPreNap, 'monthly');

    paper.daily();
    paper.daily();
    paper.daily();
    paper.monthly();


    makePublisher(joe);

    joe.tweet = function (msg) {
        this.publish(msg);
    };

    paper.readTweets = function (tweet) {
        alert('Call big meeting! Someone ' + tweet);
    };

    joe.subscribe(paper.readTweets);

    joe.tweet("hated the paper today");

results matching ""

    No results matching ""