观察者模式
定义
观察者模式(Observer Pattern): 定义对象间一种一对多的依赖关系,使得当每一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。观察者模式是一种对象行为型模式。
观察者模式包含两个角色:
- 主题(Subject):被观察的对象,它维护了一个观察者列表,可以添加、删除观察者,以及通知观察者状态的变化。
- 观察者(Observer):观察主题的对象,当主题状态发生变化时,它会接收到通知并进行相应的处理。
为什么需要观察者模式
观察者模式的价值在于它可以将主题对象和观察者对象解耦,使得它们可以独立地进行扩展和修改,同时也可以降低代码的耦合度,提高代码的可维护性和可扩展性。
具体来说,观察者模式有以下几个价值:
- 易于扩展
观察者模式可以在不修改主题对象和观察者对象的情况下,增加新的观察者对象或者新的主题对象,从而实现系统的扩展性。
- 解耦
观察者模式将主题对象和观察者对象解耦,使得它们可以独立地进行扩展和修改,降低了它们之间的依赖关系,提高了系统的灵活性。
- 通信
观察者模式通过事件通知的方式,实现了主题对象和观察者对象之间的通信,使得它们可以相互交流和协作,从而实现系统的功能。
总之,观察者模式可以帮助我们更好地组织代码,降低代码的耦合度,提高代码的可维护性和可扩展性,应用广泛,是一种非常有价值的设计模式。
具体实现
class Subject<T> {
private list: Observer<T>[] = []
constructor(private _state: T) {
}
get state() {
return this._state
}
add(observer: Observer<T>) {
this.list.push(observer)
}
remove(observer: Observer<T>) {
const index = this.list.findIndex(o => o === observer)
index > -1 && this.list.splice(index, 1)
}
notice() {
this.list.forEach(observer => {
observer.update(this)
})
}
changeState(state: T) {
this._state = state
this.notice()
}
}
class Observer<T> {
constructor(subject: Subject<T>) {
subject.add(this)
}
update(subject: Subject<T>) {
console.log('update:', subject.state)
}
}
应用场景
- DOM事件监听
常见的如click事件、mouse事件、keyboard事件等,通过addEventListener()方法注册事件,当事件触发时,将自动调用回调函数。 - Promise对象
Promise对象可作为一种观察者模式实现异步编程,当Promise对象状态发生改变时,所有订阅者都会得到通知并执行其回调函数。