用ts学习观察者模式

观察者模式 (Observer Pattern)

定义:在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

举个例子: 气象站

主题是天气。

根据检测到的天气,需要展示不同的信息,比如

以下四个观察者:

1、观察最高温度,最低温度,平均温度。
2、观察天气推荐穿衣搭配的建议。
3、观察显示当前天气的各种数据。
4、观察预测将来的天气(天气预报)。

学习观察者模式需要了解的知识点:

主题

主题是被观察的对象,它持有许多观察者,可以动态的添加删除观察者,以及通知观察者自身的变化。

interface Subject {
    registerObserver(observer:Observer):void
    removeObserver(observer:Observer):void
    notifyObservers(observers?:Array):void
}

以上是主题接口,对象使用此接口注册为观察者,或者把自己从观察者中删除。

观察者

观察者拥有一个 updata 函数,当收到主题的通知时调用 updata 更新数据。

interface Observer {
    updata(params?:any):void //根据实际项目自定义参数
}

以上是观察者接口,所有潜在的观察者必须实现观察者接口,这个接口只有 updata 一个方法。

使用观察者模式实现气象站

现在我们来用观察者来实现一个气象站。

实现天气主题

class WeatherData implements Subject {
    private observers: Array // 观察者
    private temperature: number // 温度
    private humidity: number // 湿度
    private pressure: number // 压力
    constructor(){
        this.observers = []
        this.run()
    }
    public registerObserver(observer:Observer) { //注册观察者
        this.observers.push(observer)
    }
    public removeObserver(observer:Observer) { //注销观察者
        let index = this.observers.indexOf(observer)
        if(index!==-1){
            this.observers.splice(index,1)
        }
    }
    public notifyObservers(observers = this.observers) { // 通知观察者
        for(let observer of observers){
            observer.updata(this.temperature,this.humidity,this.pressure) // 更新
        }
    }
    getTemperature(){ // 获取温度
        return this.temperature
    }
    getHumidity(){ // 获取湿度
        return this.humidity
    }
    getPressure(){ // 获取压力
        return this.pressure
    }
    measurementsChange(temperature:number,humidity:number,pressure:number) {
        this.temperature = temperature
        this.humidity = humidity
        this.pressure = pressure
        this.notifyObservers() // 通知观察者
    }
    run(){
        setTimeout(() => {
            let temperature = Math.random()*38 - 10
            let humidity = Math.random()
            let pressure = 95 + Math.random()*5
            this.measurementsChange(Number(temperature.toFixed(1)),Number(humidity.toFixed(1)), Number(pressure.toFixed(1)))            
        }, 0);
        setInterval(()=>{
            let temperature = Math.random()*38 - 10
            let humidity = Math.random()
            let pressure = 95 + Math.random()*5
            this.measurementsChange(Number(temperature.toFixed(1)),Number(humidity.toFixed(1)), Number(pressure.toFixed(1)))
        },1000*4)
    }
}

实现当前天气

class CurrentWeatherDisplay implements Observer, DisplayElement{ // 当前天气
    private temperature: number // 温度
    private humidity: number // 湿度
    private pressure: number // 压力
    private view:HTMLElement // 布告栏天气视图
    constructor(view:HTMLElement){
        this.view = view
    }
    updata(temperature:number,humidity:number,pressure:number){
        this.temperature = temperature
        this.humidity = humidity
        this.pressure = pressure
        this.display()
    }
    display(){
        this.view.innerHTML= `
        
当前温度:${this.temperature.toFixed(2)}
当前湿度:${this.humidity.toFixed(2)}
当前压力:${this.pressure.toFixed(2)}
` } }

初始化

    const bulletinBoard = document.body // 布告栏

    const weatherData = new WeatherData() // 天气
    
    const currentWeatherDisplayView = document.createElement('div') // 创建一个div显示 当前天气
    
    const currentWeatherDisplay = new CurrentWeatherDisplay(currentWeatherDisplayView) // 当前天气
    
    weatherData.registerObserver(currentWeatherDisplay) // 将当前天气注册成观察者

    bulletinBoard.appendChild( // 在布告栏绑定当前天气
        currentWeatherDisplayView
    )

相关代码 demo02

(完)

你可能感兴趣的:(用ts学习观察者模式)