发布订阅模式和观察者模式理解

167 阅读1分钟

发布订阅模式和观察者模式的区别

发布订阅模式,需要有三个角色,事件中心,发布者,订阅者,相当于eventBus

class Event{
constructor(){
  //储存订阅者
  this.listeners = {}
}
//订阅方法,listern是一个回调函数
on(eventType,listeners){
  if(!this.listeners[eventType]){
    this.listeners[eventType] = []
  }
  this.listeners[eventType].push(listeners)
  console.log(this.listeners[eventType])
}
//发布,data为发布内容
emit(eventType,data){
  const callback = this.listeners[eventType]
  if(callback){
    callback.forEach(e=>{
      e(data)
    })
  }
}
}
const event = new Event()
//订阅的地方可以获取到对象
event.on('open',data=>{
console.log('订阅一个事件',data)
})
event.on('haha',data=>{
console.log(data)
})
//发布了一个对象
event.emit('open',{open:true})
event.emit('haha',{haha:true})

event.on 订阅事件,event.emit 发布事件

观察者模式

1.使用Object.defineProperty(obj,targetValue,callback)

function observer(obj,targetValue,callback){
  if(!obj.data){
    obj.data = {}
  }
  Object.defineProperty(obj,targetValue,{
    get(){
      return this.data[targetValue]
    },
    set(val){
      this.data[targetValue] = val
      callback && callback(val)
    }
  })
  if(obj.data[targetValue]){
    callback && callback(obj.data[targetValue])
  }
}
const obj = {
  data:{descript:'ccc'}
}
observer(obj,'descript',value=>{
  console.log(value)
})

2.使用Proxy和Reflect

const queueObservers = new Set()

const observe = fn => queueObservers.add(fn)

//添加代理
const observeable = obj=> new Proxy(obj,{set})

function set(target,key,value,receiver){
  const result = Reflect.set(target,key,value,receiver)
  queueObservers.forEach(observer=>observer())
  return result
}

const person = observeable({
  name:'张三',
  age:20,
})
function print(){
  console.log(`${person.name}`,`${person.age}`)
}
observe(print)
person.name='李四'

总结观察者模式和发布订阅模式两者的差异

  • 观察者模式,观察者和观察对象两者之间是相互知道的,耦和性较高,发布订阅模式,事件中心,订阅者,发布者,两者之间不用相互知道,他们通过事件中心来通知事件的变化,解耦性高