《设计模式》之观察者模式

观察者模式

定义:

观察者模式:在对象之间定义一对多的依赖,这样依赖,当一个对象改变状态,依赖它的对象都会受到通知,并自动更新

这个模式在很多场景下都有用到:

  • 比如消息队列,订阅一个主题的消息,当该类主题有消息到达时,通知其所有的订阅者;
  • 比如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]: 被雨声吵醒,很生气,骂骂咧咧的起来关窗! 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。