关于观察者模式应该是在js中使用最为广泛的一种设计模式了,这里将从以下几个方面记录观察者模式:
观察者模式的定义
观察者模式的常见的使用场景
观察者模式的简单实现
观察者模式的设计原则分析
- 何为观察者模式:
观察者模式是一种行为模式,比较正式一点的定义是:当一个对象的状态发生变化时,能够通知其他关联的对象进行状态的刷新。举一个生活中的例子:当我们去饭店吃饭时,点好饭菜之后就可以坐在一旁等待,当饭菜做好之后,服务员会通知我们去拿菜,而实际的饭菜什么时候会做好并没有一个具体的时间,我们是等待服务员通知。这便是一个观察者模式很好的一个生活中的例子。实际的一个对象的状态什么时候发生变化我们并不清楚,但是当他的状态发生改变后我们又确实需要去知道,这便是观察者模式一个很好的应用场景了。
关于观察者模式,会经常提到的两个概念是发布订阅和一对多,对于发布订阅模式和观察者模式还是有一定区别的,观察者模式是一个对象发生变化会直接通知观察者进行相应的状态变更,而发布订阅模式则会多一个中间层,由发布者通知中间层,再由中间层通知给给个观察者进行状态的变更。除此之外一对多的概念是一个发布者可以对应一个或者是多个观察者。 - 观察者模式常见的使用场景:
- js中比较常见的一个场景就是事件绑定了,通过订阅事件,当事件被触发时去调用给定的回调函数
- ES6中经常用到的Promise对象也是一个观察者模式很好的实例:当定义Promise对象时是处于pending状态的,等到相应的操作执行时调用resolve或者是reject函数时便是通知给外部执行回调
- nodejs中的自定义事件也是一个观察者模式:通过EventEmitter类实例的对象可以使用on()方法进行事件的监听,而事件什么时候被触发则是需要通过emit()方法去处理,当emit()方法触发则去通知执行on监听事件给定的回调
- nodejs中读取post请求的数据(这个文件流操作比较相似)当数据来的时候开始接受数据,当数据发送结束时通知发送数据发送结束,调用on(‘end’)指定的回调函数
…
当然,观察者模式在js中的具体应用场景还有很多很多,这里就不一一列举了
- 观察者模式的简单实现:
// 首先定义一个Suject的被观察类:
class Subject{
constructor(){
// 定义一个观察者的数组,所有的观察者都会被加入到这个数组中
this.observer = []
// 定义一个随机的状态
this.state = 0
}
// 获取对象的state的方法:
getState(){
return this.state;
}
// 设置对象state的方法:
setState(state){
this.state = state;
this.notifyAllObserver()
}
// 定义notifyAllObserver()方法通知所有的观察者
notifyAllObserver(){
this.observer.forEach(observer => {
// 掉用observer的update方法更新状态
observer.update()
})
}
// 为该对象添加观察者的方法
attach(observer){
this.observer.push(observer)
}
}
// 定义观察者类:
class Observer{
constructor(name, subject){
this.name = name;
this.subject = subject;
this.state = subject.getSatet();
this.subject.attach(this);
}
// 更新状态的函数
update(){
this.state = this.subject.getState()
}
}
// 测试:
const subject = new Subject()
const o1 = new Observer("观察者1", subject)
const o2 = new Observer("观察者2", subject)
let state = 1;
setInterval(() => {
subject.setState(state)
state++;
}, 1000)
分析代码: 定义了一个Subject类做为发布者,类中定义了一个订阅者对象的数组用于进行状态更新的通知,而状态更新时的setState()方法执行时就遍历订阅者数组进行通知。而Observer类为订阅者类,其中传入了发布者类的对象,并在其构造函数中将该订阅者通过Subject对象的attach()方法加入到发布者订阅列表中,同时定义一个update方法让Subject调用进行状态的更新
- 设计原则分析
最后我们来分析一下观察者模式是否符合设计原则:
- 观察者模式将发布者和观察者两者分开,不是主动的去触发,而是被动的监听发布者的状态变化,两者解耦
- 符合开放封闭原则:能够不断扩展订阅者的数量和扩展具体的内容
关于观察者模式就记录到这里了 大家 加油!!!