JS设计模式--发布/订阅模式和观察者模式

 之前一直都认为观察者模式和发布订阅模式是一回事,包括网上的很多文章也是这么写的,但有一次面试中被问到两者的区别,直接懵了答不出来,经过最近的一些学习,慢慢理解了两者的不同。
 在我看来,两者最主要的区别在于是否有中间的调度中心。

  1. 观察者模式把订阅者维护在发布者这里,需要发布消息时直接发消息给订阅者。在观察者模式中,发布者本身是知道订阅者存在的。
  2. 而发布/订阅模式中,发布者并不维护订阅者,也不知道订阅者的存在,所以也不会直接通知订阅者,而是通知调度中心,由调度中心通知订阅者。

由以上的描述可以看出,发布订阅模式是松散耦合的,而观察者模式强耦合。
观察者模式的场景:Vue的依赖追踪,原生事件。
发布订阅模式的场景: React的合成事件,vue组件间通信的EventBus。
观察者模式的一个例子:

class Observer {
  constructor (fn) {
    this.update = fn
  }
}
class Subject {
  constructor () {
    this.observers = []
  }
  addObserver (observer) {
    this.observers.push(observer)
  }
  removeObserver (observer) {
    const delIndex = this.observers.indexOf(observer)
    this.observers.splice(delIndex, 1)
  }
  notify () {
    this.observers.forEach(observer => {
      observer.update()
    })
  }
}

var subject = new Subject()
var ob1 = new Observer(function () {
  console.log('ob1 callback run')
})
subject.addObserver(ob1)
var ob2 = new Observer(function () {
  console.log('ob2 callback run')
})
subject.addObserver(ob2)
subject.notify()

发布/订阅模式:

class EventBus {
  constructor () {
    this.events = Object.create(null)
  }
  on (event, fn) {
    this.events.event = this.events.event || []
    this.events.event.push(fn)
  }
  off (event, fn) {
    const index = (this.events.event || []).indexOf(fn)
    if (index < -1) {
      return
    } else {
      this.events.event.splice(index, 1)
    }
  }
  fire (event) {
    this.events.event.forEach(fn => fn())
  }
}
var bus = new EventBus()
bus.on('onclick', function () {
  console.log('click1 fire')
})
bus.on('onclick', fn=function () {
  console.log('click2 fire')
})
bus.fire('onclick')

你可能感兴趣的:(JS设计模式--发布/订阅模式和观察者模式)