什么是观察者模式?观察者模式能做什么?
观察者模式定义了一种一对多的依赖关系,让多个观察者同时监听一个目标对象,当这个目标对象的状态发生变化时,会通知所有的观察者,使他们能够自动更新。—— Graphic Design Patterns
ok 我们搞懂了定义,就大概知道了,首先需要两个基础的类。
- 发布者类(发布通知,使观察者自动更新)
- 观察者类(观察发布者)
开始定义这两个类
发布者
首先思考,发布者需要什么方法?
- 增加订阅者
- 移除订阅者
- 发布通知
明确目标后,开始动手~
class Publisher{
constructor(){
this.observers = [] // 定义订阅者数组,默认为空
}
addObserver(obs){
this.observers.push(obs) // 增加订阅者,最好可以去重,防止重复发布
}
removeObserver(obs){
const idx = this.observers.findIndex( item => item === obs)
this.observers.splice(idx,1) //删除匹配到的订阅者
}
notify(){
this.observers.forEach(obs => {
obs.update(this) // 通知订阅者们,并且把当前的实例传过去
})
}
}
订阅者
再思考思考订阅者要有什么功能?其实订阅者的功能比较单一,就是接到通知,开始工作。
class Observer{
constructor(){
// 基础数据
}
update(state){
// 更新操作
}
}
这样我们两个基础的类就定义好了,接下来模拟一个真实场景,来体验一下观察者模式的应用~
场景
产品经理阿黄拉了一个钉钉群,并且把程序员A,B,C拉进了群里,说道:过两天会有一个需求,不过现在需求细节还在等业务确认,大家伙先留意一下群消息,需求出来之后希望优先处理我的需求。
此时,程序员A,B,C就是订阅者,阿黄就是发布者,具体落实到代码中就是如下:
// 继承于上面两个基类
// 产品经理(发布者)
class PrdPublisher extends Publisher{
constructor(){
super()
this.observers = [] //还没拉群,所以没有程序员
this.prdState = null //需求文档还要找业务确认,暂时为null
}
getPrdState(){
return this.prdState
}
setPrdState(state){
this.prdState = state
this.notify() //继承过来的方法
}
}
// 程序员(订阅者)
class DeveloperObserver extends Observer{
constructor(){
super()
this.prdState = null //产品经理还没给需求文档,暂时为null
}
update(publisher){
this.prdState = publisher.getPrdState() // 把产品的文档拿到手
this.work()
}
work(){
// 开始 996
console.log(this.prdState)
console.log('开始 996')
}
}
类创建好了,之后阿黄开始工作了
// 阿黄出生了
const aHuang = new PrdPublisher()
// 程序员们来了
const A = new DeveloperObserver()
const B = new DeveloperObserver()
const C = new DeveloperObserver()
// 拉群了
aHuang.addObserver(A)
aHuang.addObserver(B)
aHuang.addObserver(C)
// T人了
aHuang.removeObserver(C) //发现A和B就能搞定这个需求,C去做其他需求吧!
// 跟业务确认完毕
aHuang.setPrdState({name:'需求文档第一百版'})