日期:2014-05-16  浏览次数:20510 次

JS实现观察者模式
  作者:zhanhailiang 日期:2012-10-24

基本概念介绍

观察者(observer) 模式广泛用于客户端Javascript编程中。所有的浏览器事件都是该模式的例子。它的另一个名字也称为自定义事件(custom events),与那些由浏览器触发的事件相比,自定义事件表示是由你编程实现的事件。此外,该模式的另一个别名也称为订阅/发布(subscriber/publisher)模式。

设计该模式背后的主要动力是促进形成松散耦合。在这种模式中,并不是一个对象调用另一个对象的方法,而是一个对象订阅另一个对象的特定活动并在状态改变后获得通知。订阅者也称为观察者,而补观察的对象称为发布者或主题。当发生了一个重要的事件时,发布者将会通知(调用)所有订阅者并且可能经常以事件对象的形式传递消息。

示例:杂志订阅

假设有一个发布者paper,它每天出版报纸及月刊杂志。订阅者joe将被通知任何时候所发生的新闻。

该paper对象需要一个subscribers属性,该属性是一个存储所有订阅者的数组。订阅行为只是将其加入到这个数组中。当一个事件发生时,paper将会循环遍历订阅者列表并通知它们。通知意味着调用订阅者对象的某个方法。故当用户订阅信息时,该订阅者需要向paper的subscribe()提供它的其中一个方法。

paper也提供了unsubscribe()方法,该方法表示从订阅者数组(即subscribers属性)中删除订阅者。paper最后一个重要的方法是publish(),它会调用这些订阅者的方法,总而言之,发布者对象paper需要具有以下这些成员:

1.subscribers 一个数组 2.subscribe() 将订阅者添加到subscribers数组中 3.unsubscribe() 从subscribers数组中删除订阅者 4.publish() 循环遍历subscribers数组中的每一个元素,并且调用他们注册时所提供的方法

所有这三种方法都需要一个type参数,因为发布者可能触发多个事件(比如同时发布一本杂志和一份报纸)而用户可能仅选择订阅其中一种,而不是另外一种。

由于这些成员对于任何发布者对象都是通用的,故将它们作为独立对象的一个部分来实现是很有意义的。那样我们可将其复制到任何对象中,并将任意给定对象变成一个发布者。

如下实现一个通用发布者

var publisher = {
    subscribers: {
        any: [] // event type: subscribers
    },