观察者模式和发布订阅模式的简单实现

观察者模式

给一个主题添加若干个观察者,若主题有变更,则通知所有的观察者,观察者收到通知后可以做一些处理,下面是一个简易版的实现

// 主题类
class Subject {
  constructor () {
    this.watchers = []
  }
  // 添加一个观察者
  addWatcher (watcher) {
    this.watchers.push(watcher)
  }
  // 删除一个观察者
  removeWatcher (watcher) {
    this.watchers = this.watchers.filter(item => item !== watcher)
  }
  // 通知所有观察者
  notify (msg) {
    this.watchers.forEach(watcher => {
      watcher.update(msg)
    })
  }
}

// 观察者类
class Watcher {
  constructor (name) {
    this.name = name
  }
  // 收到通知后的处理
  update (msg) {
    console.log(this.name + ' => ' + msg)
  }
  // 订阅主题
  addToSub (sub) {
    sub.addWatcher(this)
  }
}

let sub = new Subject()
let w1 = new Watcher('w1')
let w2 = new Watcher('w2')
w1.addToSub(sub)
w2.addToSub(sub)
sub.notify('hello world!')

发布订阅模式

用一个调度中心统一处理发布和订阅,下面是一个 js 版本的简单实现:

// 调度中心类
class Dispatch {
  constructor () {
    this.subscribers = {}
  }
  // 添加一个订阅
  subscribe (type, fun) {
    if (!this.subscribers[type]) this.subscribers[type] = [fun]
    else this.subscribers[type].push(fun)
  }
  // 取消订阅
  unsubscribe (type) {
    this.subscribers[type] && delete this.subscribers[type]
  }
  // 发布消息
  publish (type, msg) {
    let target = this.subscribers[type]
    target && target.length && target.forEach(fun => {
      fun(msg)
    })
  }
}

let disp = new Dispatch()
disp.subscribe('type1', msg => { console.log(msg) })
disp.subscribe('type2', msg => { console.log(msg) })
disp.publish('type1', 'hello')
disp.publish('type2', 'world')

下面是一个 Vue 版本的简单实现

// EventBus.js
import Vue from 'vue'
export default new Vue()

// comp1.vue
EventBus.$on('test', v => {
  console.log(v) // johnhan
})

// comp2.vue
EventBus.$emit('test', 'johnhan')
除特殊说明外本人博客均属原创,转载请注明出处:http://blog.johnhan.cn/blog_1105.html
京ICP备19044523号-1