ts implements simple observer mode

What is the observer pattern

The observer pattern is a design pattern that allows you to always be aware of changes in the state of an object. It is a one-to-many dependency relationship, such as a newspaper subscription.

The observer pattern can be seen everywhere in life (headhunters and job seekers):

headfirst design pattern weather station case

There are two ways to notify updates: pushing the topic to the observer and pulling the topic by the observer. Most implementations use push, and the push method is also used here.

The weather station needs to design a subject (Subject), which contains three states: temperature, humidity and air pressure. It is required that when the state of the subject changes, it must notify the three status bulletin boards to be updated. The type of bulletin board is required to be extensible. ,the state of the topic is extensible

The weather station is regarded as an object here. It has some states and is extensible. Here it is represented by an object, and the extended states can be added to it:

type WeatherData = Partial<{
  temperature: string // 气温
  humidity: string // 湿度
  pressure: string // 气压
}>

Think of each bulletin board as an observer, which consists of two functions: update (update) and display (display). The update method is necessary and is uniformly called update. Update is called when the weather station theme status changes. This process is to notify the update

Because different types of bulletin boards display the same content, the observer should be an interface

interface Observer {
  update: (data: WeatherData) => void // 更新状态
  display: (data: WeatherData) => void // 展示主题
}

The theme should also be an interface, which contains some public APIs:

interface Subject {
  changed: boolean // 标记状态是否更新
  observers: Observer[] // 所有观察者的集合
  setMeasurementsChanged?: (data: WeatherData) => void // 设置检测值
  measurementsChanged?: (data: WeatherData) => void // 检测值发生变化时调用通知观察者更新
  addObserver: (observer: Observer) => number // 注册观察者
  deleteObserver: (observer: Observer) => boolean // 取消订阅观察者
  notifyObservers: (data: WeatherData) => void // 通知观察者更新  推送最新状态
  setChanged: () => void // 状态变更的标记位
}

Define the weather station class to implement the theme interface:

class Weather implements Subject {
  state: WeatherData // 记录气象站状态
  changed: boolean // 是否更新的标记位
  observers: Observer[] // 观察者集合
  constructor() {
    this.observers = [] // 初始化观察者集合
  }
  // 状态变化的钩子
  measurementsChanged(data: WeatherData) {
    console.log('气象站主题更新了,通知观察者更新--------------------')
    this.notifyObservers(data) //
  }
  // 这个方法状态有新值时供外界调用触发更新
  setMeasurementsChanged(data: WeatherData) {
    this.state = data
    // 这里可以控制更新的条件 利于条件控制状态的更新频率 比如温差超过5度或者某个字段变化了才通知更新 可以写自己的变化逻辑
    // if(data.temperature-this.state.temperature>=5) // 伪代码举例 这里的字段并不是数字类型 这里根据实际情况设计
    if (true) {
      this.setChanged(true)
    }
    this.measurementsChanged(data)
  }
  addObserver(observer: Observer) {
    return this.observers.push(observer)
  }

  deleteObserver(observer: Observer) {
    const idx = this.observers.findIndex((e) => e === observer)
    if (idx >= 0) {
      this.observers.splice(idx, 1)
      return true
    }
    return false
  }
  notifyObservers(data: WeatherData) {
    if (!this.changed) return // 如果没有更新则不通知
    // 遍历所有的观察者通知更新
    for (const observer of this.observers) {
      observer.update(data)
    }
    this.setChanged(false) // 通知更新后修改是否更新状态为false
  }
  // 设置是否有更新的标志
  setChanged(flag: boolean) {
    this.changed = flag
  }
}

After having the weather station class, implement the observer class

// 气温观察者
class TemperatureObserver implements Observer {
  update(data: WeatherData) {
    this.display(data)
  }
  display(data: WeatherData) {
    console.log('温度观察者:', data.temperature)
  }
}
// 湿度观察者
class HumidityObserver implements Observer {
  update(data: WeatherData) {
    this.display(data)
  }
  display(data: WeatherData) {
    console.log('湿度观察者:', data.humidity)
  }
}
// 气压观察者
class PressureObserver implements Observer {
  update(data: WeatherData) {
    this.display(data)
  }
  display(data: WeatherData) {
    console.log('气压观察者:', data.pressure)
  }
}

Different types of bulletin boards implement the observer interface to define their own display behaviors. They must implement the update method, and then add observers to the weather station and notify updates.

const subject = new Weather() // 创建气象站主题
// 添加观察者
subject.addObserver(new TemperatureObserver())
subject.addObserver(new HumidityObserver())
subject.addObserver(new PressureObserver())
// 气象站状态发生改变
subject.setMeasurementsChanged({
  temperature: '37度',
  humidity: '干燥',
  pressure: '101帕',
})
subject.setMeasurementsChanged({
  temperature: '38度',
  humidity: '滋润',
  pressure: '99帕',
})

The console prints the results, and two successful status changes notify the update.

 The above is a simple case of observation mode. The original case was implemented in Java. After understanding it, I rewrote it in ts. The responsive principle of Vue also uses the observer mode, which notifies the update page of data changes.

Guess you like

Origin blog.csdn.net/Suk__/article/details/128662425