观察者模式和发布/订阅模式
观察者模式,英文名:Observer模式。
基本概念:一个对象(目标)维持一系列依赖于它的对象(观察者),将有关状态的任何变更自动通知给它们(观察者)。
当一个目标需要告诉观察者发生了什么事情时,它会向观察者广播一个通知。当目标不再希望某个特定的观察者获得其注册目标发出的通知时,该目标可以将它(某个特定的观察者)从观察者列表中删除。
目标(subject):维护一系列的观察者,方便添加或删除观察者。
观察者(Observer):在目标状态发生改变时,需要获得通知的对象。
以上是观察者模式的概念,在实际项目应用中,我们需要有4个对象:
目标(subject),观察者(observer),具体目标(concretesubject),具体观察者(concreteobserver)。
举个例子:
页面上有一个radio,选择上,div就显示,没选择上,div就消失。
目标:obj,它有两个方法,一个是addObserver,一个是removeObserver。
观察者:obj1
具体目标:页面上面的单选框radio
具体观察者:页面上面的div
首先,我们把目标obj的属性和方法扩展到具体目标radio中,这样radio就拥有可以添加观察者和删除观察者的方法。
然后,我们把观察者obj1的属性和方法扩展到具体观察者div中,这样radio就可以添加div了。
最后,我们使用radio添加3个div,也就是说,现在这三个div是观察者,radio是目标。只要radio改变,就会发通知给这三个div。
现在,我们来看整个的执行过程:当我们点击radio时,它的状态会改变(被选择上到被取消,被取消到被选择上),这时,radio的状态变化会告诉这三个div,如果radio被选择上,div就显示,如果被取消,div就隐藏。(radio绑定了onclick事件,它的回调方法中会调用这三个div的显示或隐藏方法)。
发布/订阅模式,英文名:publish/subscribe模式。
此模式属于观察者模式,但有一定的区别,它跟观察者模式最大的区别是订阅者和发布者之间的依赖性低。我们可以把发布者看做目标,订阅者看做观察者。
发布/订阅模式在浏览器中很常见,事件的监听就是一个最简单的发布/订阅模式。我们平常在进行事件绑定时,绑定的元素就是发布者,回调方法中所做的处理(比如:显示一个div),这个div就是一个订阅者。
举个例子:
一个负责显示实时股票信息的web应用程序。
该应用程序有一个显示股票统计的网格和一个显示最后更新点的计数器。当数据模型改变时,应用程序需要更新网格和计数器。在这种情况下,目标(它将发布通知)就是数据模型,观察者就是网格和计数器。
当观察者接收到model(目标)已经改变的通知时,则可以相应的更新自己。
发布/订阅模式最大的作用是解耦我们的js代码,以至于我们可以更好的实现js代码的管理和复用。
最后一个例子:
使用发布/订阅模式解决ajax代码耦合的问题。
通常在侧重ajax技术的应用程序中,一旦我们收到了请求的响应,我们就想据此实现不只一个特定动作。由于函数或代码之间互相依赖的增加,高度耦合的应用程序会增加复用函数所需的工作量(会写很多重复的代码,比如:多个ajax请求时)。
使用发布/订阅模式的好处是:我们可以有10个不同的订阅者以不同的方式使用ajax请求返回来的数据,对于ajax,它唯一的责任是请求服务器和获得数据,然后传递给任何想使用此数据的订阅者。这种代码的分离,可以让10个不同的订阅者使用一次ajax请求,就能搞定,如果不使用此模式,这10个订阅者要进行10次ajax请求,才能搞定。并且,使用此模式,可以把ajax请求的代码抽出来做成公共的方法,达到代码或函数复用的作用。
加油!