JavaScript设计模式-观察者模式

观察者模式又被称为发布-订阅模式,是一种常见的行为型模式,主要用来处理不同对象之间的交互通信问题,我们平时常用的DOM事件,也是使用观察者模式实现的。

观察者模式一般包含两种对象:

  1. 发布者对象:发布通知,通知订阅者
  2. 订阅者对象:监听通知,响应通知

举个栗子:

document.body.onclick = function(){
    alert('我是观察者,你一点击,我就知道了');
}

我们可以看到,在这个click事件中,body是事件的发布者,当它被点击时,就会通知观察者这一事件,而事件处理函数就是观察者,接收到click事件时立即响应,执行函数。

下面,我们就来实现一个简单的观察者模式的实例。观察者对象应该有如下属性和方法:

  • 一个由回调函数构成的订阅者数组;
  • 用于添加和删除订阅者的addSubscriber()和removeSubscribrt()方法;
  • 推送通知的publish()方法;
  • 将任意对象转变为一个发布者、并为其添加上述方法。
var Observer = {
    subscribers: [],        // 订阅者数组
    addSubscriber: function (callback) {
        if (typeof callback === "function") {
            this.subscribers[this.subscribers.length] = callback;
        }
    },
    removeSubscriber: function (callback) {
        for (var i = 0; i < this.subscribers.length; i++) {
            if (this.subscribers[i] === callback) {
                delete this.subscribers[i];
            }
        }
    },
    publish: function (msg) {
        for (var i = 0; i < this.subscribers.length; i++) {
            if (typeof this.subscribers[i] === "function") {
                this.subscribers[i](msg);
            }
        }
    },
    make: function (obj) {
        for (var k in obj) {
            if (this.hasOwnPropety(k)) {
                obj[k] = this[k];
                obj.subscribers = [];
            }
        }
    }
}

接下来我们创建一个订阅者,订阅者可以是任意对象,他们唯一的作用是在事件发生时调用publish()方法。下面是一个weibo对象,每当更新微博时,就会调用publish()方法。

var weibo = {
    pushWeiboPost: function () {
        var content = "Today is " + new Date();

        this.publish(content);
    }
}

然后将他们转变为发布者:

Observer.make(weibo);

然后我们再建立一个订阅者对象并订阅微博更新:

var jack = {
    read: function (msg) {
        console.log("I just read that" + msg);
    }
}
weibo.addSubscriber(jack.read);

然后,当weibo发布消息时会发生什么呢?

weibo.pushWeiboPost();
// I just read that Today is Sun Feb 28 2016 20:14:21 GMT+0800 (CST)

任何时候,jack都可以取消订阅,于是就再也收不到通知消息了:

weibo.removeSubscriber(jack.read);