發佈訂閱和觀察者模式的區別

有些人認爲觀察者模式就是發佈訂閱模式,實際上觀察者模式是包含了訂閱發佈模式,發佈訂閱模式只是觀察者模式中的一種。觀察者模式是觀察者和被觀察者之間的通訊,而發佈訂閱模式中間增長了一箇中轉層,經過第三方來分發信息。vue

觀察者模式

// Subject爲被觀察者,Subject中的狀態(state)改變,就通知 Observer更新
    class Subject {
      constructor() {
        this.observes = []
        this.state = false
      }
      // this.observes存儲觀察者
      attach(observe){
        this.observes.push(observe)
      }
      // 狀態改變,通知 Observer 觸發更新
      setState(newState){
        this.state = newState
        this.observes.forEach( observer => observer.update(newState))
      }
    }
    // Observer爲觀察者,觀察Subject的狀態是否改變
    class Observer {
      constructor(name) {
        this.name = name
      }
      // 更新
      update(state){
        console.log(this.name + ",接收到了通知,被觀察者的屬性變爲 " + state)
      }
    }
    var sub = new Subject()
    var obs1 = new Observer('觀察者1')
    var obs2 = new Observer('觀察者2')
    sub.attach(obs1)
    sub.attach(obs2)
    // 被觀察者的狀態改變,觸發觀察者更新
    sub.setState(true)

vue中數據劫持中就用到了觀察者模式,data中的屬性一發生變化,就通知view界面更新,從而實現數據驅動,想要進一步瞭解vue底層原理,能夠參考能夠參考github上的一篇文章 ☛ MVVM實現git

觀察者模式

// 發佈訂閱
    class Events {
      constructor() {
        this.sub = {} // 容器
      }
      // 根毫不同 name,訂閱對應函數
      $on(name, fn) {
        const wrap = this.sub[name] || (this.sub[name] = [])
        wrap.push(fn)
      }
      // 遍歷全部相同name的訂閱函數,併發布
      $emit(name, ...args) {
        const fns = this.sub[name] || []
        fns.forEach(fn => {
          fn.apply(this, args)
        })
      }
      // 銷燬,避免內存泄漏
      $of(name){
        this.sub[name] = null
      }
    }
    // event 至關於中轉器
    const event = new Events()
    // 訂閱
    event.$on('eventname', function (a, b) {
      console.log(a, b)
    })
    event.$on('eventname', function (a, b) {
      console.log(a, b)
    })
    // 發佈
    event.$emit('eventname', 'a', 'b')

vue中的兄弟組件通訊bus的原理就是發佈訂閱模式,該模式有個缺點,當你訂閱一個消息後,也許此消息最後都未發生,但這個訂閱者會始終存在於內存中。因此該消息不使用的時候,調用$of銷燬,以免內存泄漏。github

總結

總而言之,在觀察者模式中,觀察者(Observer)是知道Subject的,Subject一直保持對觀察者進行記錄。然而,在發佈訂閱模式中,發佈者和訂閱者不知道對方的存在。它們只有經過消息代理進行通訊。觀察者模式大多數時候是同步的,好比當事件觸發,Subject就會去調用觀察者的方法。而發佈訂閱模式大多數時候是異步的。併發

相關文章
相關標籤/搜索