观察者模式
观察者模式定义了一种一或一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。典型代表 vue/react 等。
使用观察者模式的好处:
- 支持简单的广播通信,自动通知所有已经订阅过的对象。
- 目标对象与观察者存在的是动态关联,增加了灵活性。
- 目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。
当然给元素绑定事件的 addEventListener()也是一种观察者模式
target.addEventListener(type, listener [, options]);
Target 就是被观察对象 Subject,listener 就是观察者 Observer。
class 版(详细)
思路:两个构造函数(被观察者/观察者)
被观察者 Subject
- 初始化:
- 事件名 name
- 状态 state
- 观察者数组 observes
- 添加观察者 add
- 改变事件状态 setState,同时触发 forEach 观察者函数 update
- 删除观察者 delete
观察者 Observer
- 初始化:
- 观察者 name
- 触发监听函数 update
// 被观察者
//类似addEventListener('click')中的click
class Subject {
constructor(name) {
this.name = name //被观察事件
this.state = '' //被观察状态
this.observes = [] //存放观察者
}
add(Observer) {
//为了统一发送数据
this.observes.push(Observer)
}
setState(newState) {
//改变数据
this.state = newState
// 通知所有观察者数据改变:update为固定搭配
this.observes.forEach(o => o.update(newState))
}
//移除观察者
delete(Observer) {
let index = this.observes.indexOf(Observer)
this.observes.splice(index, 1)
}
}
// 观察者
//类似addEventListener('click')中的类似addEventListener
class Observer {
constructor(name) {
this.name = name //观察者
}
update(newState) {
//用来通知所有的观察者状态更新了
console.log(this.name + '发现' + newState)
}
}
//被观察者
let sub = new Subject('灯')
console.log(sub)
//观察者
let mm = new Observer('小明')
let jj = new Observer('小贱')
//订阅观察者 等价于 观察者订阅
sub.add(mm)
sub.add(jj)
//改变数据
sub.setState('开灯')
//取消观察者
sub.delete(jj)
//改变数据
sub.setState('关灯')