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

首先我们必须清楚这两种模式都是设计模式,而不是某种语言的专属;

观察者模式(Observer)

概念理解

  • 观察者模式是一种一对多的依赖关系的行为设计模式,让多个观察者对象监听一个主题对象,当主题对象发生变化时,它的所有观察者对象都会收到通知并自动更新。它可以让多个观察者对象同时监听一个主题对象,当主题对象发生变化时,可以同时通知所有观察者对象,让它们做出相应的反应;
  • Subject(被观察者)改变 --->Observer(观察者)监听到其改变,更新自己;

代码实现

//观察者模式:Subject(被观察者);Observer(观察者)
class Subject{
  constructor() {
    // 记录所有的观察者
    this.observers = []
  }
  //添加新的观察者
  addObserver() {
    this.observers.push(observer)
  }
  //移除观察者
  removeObserver() {
    let index = this.observers.indexOf(observer)
    if(index !== -1) {
      this.observers.splice(index, 1)
    }
  }
  //发布更新通知
  notify() {
    this.observers.forEach(observer => {
      observer.update()
    })
  }
}

class Observer {
  update() {
    console.log('subject has updated!');
  }
  subscribeTo(subject) {
    subject.addObserver()
  }
}
let subject = new Subject() //被观察者
let observer1 = new Observer()  //观察者
observer1.subscribeTo(subject) //观察者进行订阅
let observer2 = new Observer()  //观察者
observer2.subscribeTo(subject) //观察者进行订阅
subject.notify()

发布订阅模式(Publisher)

概念理解

  • 发布订阅模式也是一种一对多的依赖关系的行为设计模式,它可以让发布者和订阅者解耦,发布者和订阅者之间不需要知道对方的存在,发布者只需要发布消息,订阅者只需要订阅消息,当发布者发布消息时,订阅者会收到消息;
  • Publisher(发布者)改变 --->消息管道接受并通知Subscriber(订阅者) --->Subscriber(订阅者)收到通知并发生变化;

代码实现

class EventEmitter {
  constructor() {
    this.events = {}
  }
  on(name, fn) {
    if (this.events[name]) {
      this.events[name].push(fn)
    } else {
      this.events[name] = [fn]
    }
  }
  off(name, fn) {
    const tasks = this.events[name]
    if (tasks) {
      const index = tasks.findIndex((f) => f === fn || f.callback === fn)
      if (index >= 0) {
        tasks.splice(index, 1)
      }
    }
  }
  // once:是否只发生一次
  emit(name, once = false) {
    if (this.events[name]) {
      //  创建副本,如果回调函数内继续注册相同事件,会造成死循环
      const tasks = this.events[name].slice()
      for (let fn of tasks) {
        fn()
      }
      if (once) {
        delete this.events[name]
      }
    }
  }
}
posted @   Rain1112022  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示