观察者模式
定义:
观察者模式:在对象之间定义一对多的依赖,这样依赖,当一个对象改变状态,依赖它的对象都会受到通知,并自动更新
这个模式在很多场景下都有用到:
- 比如消息队列,订阅一个主题的消息,当该类主题有消息到达时,通知其所有的订阅者;
- 比如GUI编程中的那些事件处理,如鼠标的点击事件、按下键盘的事件,当发生这些事件的时候,通知其订阅者处理这些事件;
- 又比如现在服务器端开始流行起来的基于事件的,非阻塞IO模型的web框架等等;
- 又如现代的前端框架React、Vue等,使用响应式编程,观察状态的变化,更新视图;
- ...非常多场景
好莱坞有句经典名言:“Don't call me,I will call you.”
“不要整天打电话问我,有消息了我会通知你的。”
举个栗子,考虑以下场景
假设有那么几个人,在不同的场合下,对下暴雨这个事件,有不同的响应行为:
- 带伞的小张:“迅雷不及掩耳之势撑起了伞~”
- 在路边晃悠的没带伞的小王:“比兔子还快的跑到附近的商场避雨~”
- 在家的小赵:“猛然想起今天在楼顶晒了衣服,急匆匆跑上楼顶收衣服~”
- 在床上睡觉的小李:“被雨声吵醒,很生气,骂骂咧咧的起来关窗!”
实例代码:
// 这些人对下暴雨的响应接口(观察者接口)
interface IHeavyRainObserver {
onHeavyRainning?: () => void,
observe: (heavyRainObservable: HeavyRainObservable) => void,
}
// 可以被观察的下暴雨(可被观察的对象)
class HeavyRainObservable {
// 对暴雨感兴趣的人(观察者)
public observers: IHeavyRainObserver[] = []
// 下暴雨了,通知观察了的人(通知)
public startRainning() {
console.log('下暴雨了!!哗啦啦啦!!!')
for (const observer of this.observers) {
if (observer.onHeavyRainning) {
observer.onHeavyRainning()
}
}
}
}
// 增加一个抽象父类,方便观察者类添加观察
abstract class HeavyRainObserver implements IHeavyRainObserver {
public observe(heavyObservable: HeavyRainObservable) {
heavyObservable.observers.push(this)
}
}
// 带伞的小张
class Zhang extends HeavyRainObserver {
public onHeavyRainning() {
console.log('迅雷不及掩耳之势撑起了伞~')
}
}
// 在路边晃悠的没带伞的小王
class Wang extends HeavyRainObserver {
public onHeavyRainning() {
console.log('比兔子还快的跑到附近的商场避雨~')
}
}
// 在家的小赵
class Zhao extends HeavyRainObserver {
public onHeavyRainning() {
console.log('猛然想起今天在楼顶晒了衣服,急匆匆跑上楼顶收衣服~')
}
}
// 在床上睡觉的小李
class Li extends HeavyRainObserver {
public onHeavyRainning() {
console.log('被雨声吵醒,很生气,骂骂咧咧的起来关窗!')
}
}
// Test
// 创建可观察的天气对象
const weather = new HeavyRainObservable()
// 创建观察者们
const zhang = new Zhang()
const wang = new Wang()
const zhao = new Zhao()
const li = new Li()
// 观察天气情况
zhang.observe(weather)
wang.observe(weather)
zhao.observe(weather)
li.observe(weather)
// 开始下暴雨了
weather.startRainning()
输出结果:
[LOG]: 下暴雨了!!哗啦啦啦!!!
[LOG]: 迅雷不及掩耳之势撑起了伞~
[LOG]: 比兔子还快的跑到附近的商场避雨~
[LOG]: 猛然想起今天在楼顶晒了衣服,急匆匆跑上楼顶收衣服~
[LOG]: 被雨声吵醒,很生气,骂骂咧咧的起来关窗!