观察者模式&发布订阅

观察者模式

定义

观察者模式(Observer):又被称为发布-订阅模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能的耦合。 -- 出自JavaScript设计模式

争议

争议点:如果你在网上搜观察者模式和发布订阅模式你会发现,有一帮人(A派)认为这两者就是同一个东西,然而另一群人(B派)认为这两者是有本质区别的。

比如:

A派:两种写法,本质上是一样的,只是不同的实现:
1、前者要实现update方法的,可以说是偏Java的实现。因为Java中方法并不是一种对象,Java使用“Interface”的概念来表达“方法”对象,而Interface只能去实现。所以要求订阅者需要重写同一个接口中的update函数。

2、而后者可以说是更偏JS的实现,毕竟函数也是一种对象的情况下,我们是可以在订阅的时候直接传入一个函数作为参数的,这样就不需要一个实现了某种接口的对象去承载这个函数了。

B派:观察者模式处理同一类事情;发布订阅模式可以处理不同类事情。
1.观察者模式维护的是一个单一事件对应多个依赖这个事件的对象之间关系
观察者是: event->[obj1,obj2obj3,....]

2.订阅发布模式维护的是多个主题(事件) 以及依赖于各个主题(事件)的对象之间的关系
订阅发布是:{ event1->[obj1,obj2....], event2->[obj1,obj2.....],....}

我的观点

首先,实现手法上差别是有的。但是,这两者本质都是同一个思想,只不过表现形式不同。

模拟观察者模式

class Subject {
  constructor() {
    this.observers = []
  }

  add(observer) {
    this.observers.push(observer)
  }

  remove(observer) {
    const observers = this.observers
    observers.forEach((o, i) => {
      observer === o && this.observers.splice(i, 1)
    })
  }

  notify() {
    this.observers.forEach(observer => observer.update())
  }
}

class Observer {
  constructor(name) {
    this.name = name
  }

  update() {
    console.log(`${this.name} updaed`)
  }
}

const subject = new Subject()
const o1 = new Observer('o1')
const o2 = new Observer('o2')

subject.add(o1)
subject.add(o2)

// o1 updated
// o2 updated
subject.notify()

subject.remove(o2)

// o1 updated
subject.notify()

模拟发布订阅

class Event {
  constructor() {
    this.eventPool = {}
  }
  on(type, fn) {
    this.eventPool[type] ? this.eventPool[type].push(fn) : this.eventPool[type] = [fn]
  }
  emit(type, ...args) {
    this.eventPool[type] && this.eventPool[type].forEach(fn => fn(...args))
  }
}
const event = new Event()
event.on('err', console.log)
event.emit('err', 'havr error')

你可能感兴趣的:(观察者模式&发布订阅)