观察者模式
Observer Pattern
实现一个小需求
实现一个可以不断生成checkbox(check)的button(addNewObserver)
实现一个checkbox(controlCheckbox),可以控制页面上所有addNewObserver生成的check的状态
知识点一:定义
观察者模式用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应。
Subject (目标) 维护一个观察者列表,可以添加删除任意一个观察者
Observer (观察者) 负责提供一个接口(当目标状态发生改变时候,具体要怎样做)
ConcreteSubject (具体目标) 主要有两个职责: 1. 储存当前ConcreteSubject的状态 1. 状态发生改变时,向Observer发出通知
ConcreteObserver (具体观察者) 主要有两个职责: 1. 储存一个指向ConcreteSubject的引用 1. 实现Observe的更新接口,实现自身状态和目标状态保持一致
知识点二:具体实行代码
分析代码
Subject (目标) 即是当前的Subject类。它内置observers属性,透过它来负责管理一个ObserverList实例。它拥有添加(Subject.prototype.addObserver)、删除(Subject.prototype.removeObserver)一个观察者,通知观察者(Subject.prototype.notify)的能力。
Observer (观察者) 即是Observer类,提供了状态改变时获得通知对象(check),提供一个名为update的接口
ConcreteSubject (具体目标) 即本例里面的controlCheckbox,案例中职责分别为: 1. 透过执行extend( controlCheckbox, new Subject() );保存了目标实例 1. 当它被点击时候,向Observer发出通知,执行了controlCheckbox.notify( controlCheckbox.checked );
ConcreteObserver (具体观察者) 即本例里面的check,案例中职责分别为: 1. 透过执行controlCheckbox.addObserver(check) 储存一个指向ConcreteSubject的引用 1. 通过覆写 check.update 实现自身状态和目标状态保持一致
知识点三:发布订阅模式
发布订阅模式类似观察者模式,但该模式会使用一个主题/事件通道( topic/event channel)。此通道介于希望接收通知(订阅者)对象与激活事件(发布者)对象之间。此通知系统可以自定义特定事件/传递自定义参数(包括订阅者需要的值)。这样设计主要为了避免订阅者与发布者之间产生依赖关系。
中心思想是促进代码松散耦合(loose coupling)。通过订阅另一个对象的特定任务或活动,当活动发生时候获得通知,而不是通过单个对象直接调用其他对象的方法。
此模式适合在JavaScript生态系统,ECMAScript大多数的实现都是事件驱动。特别是浏览器环境下DOM使用事件作为主要的交互API。
一般的发布订阅模式,含有publish(发布)、subscribe(订阅)、unsubscribe(取消订阅)的功能
以下使用jQuery为例
知识点四:观察者模式 vs 订阅模式
相同点: 1. 具有相同的思想,都是考虑应用的不同部分,他们的驱动关系 1. 促进代码松散耦合,把应用程序分解成更小的块,提高代码复用
不同点: 观察者模式:维护多个相关对象,不需要把各个类紧密耦合。例如一个对象要通知其他对象,无需在这些对象上做太多兼容。
优点: 1. 促进代码松散耦合,把应用程序分解成更小的块,提高代码复用 1. 很容易扩展代码 1. 观察者与目标/发布者与订阅者之间动态关系,提供很大的灵活性 1. 容易测试
缺点: 1. 发布订阅模式的中间通道由于没有告诉系统信息传递的结果状态/执行结果,例如订阅者执行报错,发布者本身是不能知道 1. 随着订阅者和发布者的数量增加,信息也会随着猛增,滥用此模式会增加系统崩溃风险 1. 更改订阅者和发布者的关系会导致问题,由于大家都不认识对方 1. 内存泄漏风险,当观察者不存在,如果不手动删除,观察者会一直存在于观察者列表中
知识点五:订阅模式实现
Last updated