知食记
搜索文档…
观察者模式
1
// 定义发布者类
2
class Publisher {
3
constructor() {
4
this.observers = []
5
console.log('Publisher created')
6
}
7
// 增加订阅者
8
add(observer) {
9
console.log('Publisher.add invoked')
10
this.observers.push(observer)
11
}
12
// 移除订阅者
13
remove(observer) {
14
console.log('Publisher.remove invoked')
15
this.observers.forEach((item, i) => {
16
if (item === observer) {
17
this.observers.splice(i, 1)
18
}
19
})
20
}
21
// 通知所有订阅者
22
notify() {
23
console.log('Publisher.notify invoked')
24
this.observers.forEach((observer) => {
25
observer.update(this)
26
})
27
}
28
}
Copied!
既然我们在Publisher中做的是方法调用,那么我们在订阅者类里要做的就是方法的定义
1
// 定义订阅者类
2
class Observer {
3
constructor() {
4
console.log('Observer created')
5
}
6
7
update() {
8
console.log('Observer.update invoked')
9
}
10
}
Copied!
以上,我们就完成了最基本的发布者和订阅者类的设计和编写。在实际的业务开发中,我们所有的定制化的发布者/订阅者逻辑都可以基于这两个基本类来改写。比如我们可以通过拓展发布者类,来使所有的订阅者来监听某个特定状态的变化。仍然以开篇的例子为例,我们让开发者们来监听需求文档(prd)的变化:
1
// 定义一个具体的需求文档(prd)发布类
2
class PrdPublisher extends Publisher {
3
constructor() {
4
super()
5
// 初始化需求文档
6
this.prdState = null
7
// 韩梅梅还没有拉群,开发群目前为空
8
this.observers = []
9
console.log('PrdPublisher created')
10
}
11
12
// 该方法用于获取当前的prdState
13
getState() {
14
console.log('PrdPublisher.getState invoked')
15
return this.prdState
16
}
17
18
// 该方法用于改变prdState的值
19
setState(state) {
20
console.log('PrdPublisher.setState invoked')
21
// prd的值发生改变
22
this.prdState = state
23
// 需求文档变更,立刻通知所有开发者
24
this.notify()
25
}
26
}
Copied!
作为订阅方,开发者的任务也变得具体起来:接收需求文档、并开始干活:
1
class DeveloperObserver extends Observer {
2
constructor() {
3
super()
4
// 需求文档一开始还不存在,prd初始为空对象
5
this.prdState = {}
6
console.log('DeveloperObserver created')
7
}
8
9
// 重写一个具体的update方法
10
update(publisher) {
11
console.log('DeveloperObserver.update invoked')
12
// 更新需求文档
13
this.prdState = publisher.getState()
14
// 调用工作函数
15
this.work()
16
}
17
18
// work方法,一个专门搬砖的方法
19
work() {
20
// 获取需求文档
21
const prd = this.prdState
22
// 开始基于需求文档提供的信息搬砖。。。
23
...
24
console.log('996 begins...')
25
}
26
}
Copied!
下面,我们可以 new 一个 PrdPublisher 对象(产品经理),她可以通过调用 setState 方法来更新需求文档。需求文档每次更新,都会紧接着调用 notify 方法来通知所有开发者,这就实现了定义里所谓的:
目标对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。
OK,下面我们来看看韩梅梅和她的小伙伴们是如何搞事情的吧:
1
// 创建订阅者:前端开发李雷
2
const liLei = new DeveloperObserver()
3
// 创建订阅者:服务端开发小A(sorry。。。起名字真的太难了)
4
const A = new DeveloperObserver()
5
// 创建订阅者:测试同学小B
6
const B = new DeveloperObserver()
7
// 韩梅梅出现了
8
const hanMeiMei = new PrdPublisher()
9
// 需求文档出现了
10
const prd = {
11
// 具体的需求内容
12
...
13
}
14
// 韩梅梅开始拉群
15
hanMeiMei.add(liLei)
16
hanMeiMei.add(A)
17
hanMeiMei.add(B)
18
// 韩梅梅发送了需求文档,并@了所有人
19
hanMeiMei.setState(prd)
Copied!
以上,就是观察者模式在代码世界里的完整实现流程了。
最近更新 1yr ago
复制链接