发布订阅者模式

一、发布订阅者模式js

发布订阅者模式又称为观察者模式,是一种常见的软件设计模式,属于行为型模式。该模式定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知并被自动更新。

在JavaScript中,我们可以使用事件机制来实现发布订阅者模式。事件机制本质上就是一种发布订阅者模式的实现。我们可以通过事件机制来为一个事件注册回调函数,当这个事件触发时,所有注册的回调函数都会被依次调用。

class EventEmitter {
  constructor() {
    this._events = {}
  }
  on(event, callback) {
    if (!this._events[event]) {
      this._events[event] = []
    }
    this._events[event].push(callback)
  }
  emit(event, ...args) {
    if (!this._events[event]) {
      return
    }
    this._events[event].forEach(fn => {
      fn.apply(this, args)
    })
  }
}

二、发布订阅者模式和观察者模式代码

发布订阅者模式和观察者模式在概念上很相似,都是建立了一种一对多的依赖关系。但是它们的实现方式有所不同。在观察者模式中,观察者对象需要直接订阅主题对象,而在发布订阅者模式中,发布者和订阅者之间则没有直接的联系,而是通过发布-订阅通道来进行通信。

下面是观察者模式和发布订阅者模式的示例代码:

//观察者模式
class Subject {
  constructor() {
    this.observers = []
  }
  addObserver(observer) {
    this.observers.push(observer)
  }
  removeObserver(observer) {
    const index = this.observers.indexOf(observer)
    if (index !== -1) {
      this.observers.splice(index, 1)
    }
  }
  notify() {
    this.observers.forEach(observer => observer.update())
  }
}
class Observer {
  constructor(name, subject) {
    this.name = name
    this.subject = subject
    this.subject.addObserver(this)
  }
  update() {
    console.log(`${this.name} has been notified`)
  }
}

const subject = new Subject()
const observer1 = new Observer('observer1', subject)
const observer2 = new Observer('observer2', subject)
subject.notify() // 'observer1 has been notified', 'observer2 has been notified'

//发布订阅者模式
class EventBus {
  constructor() {
    this.subscribers = {}
  }
  subscribe(event, callback) {
    if (!this.subscribers[event]) {
      this.subscribers[event] = []
    }
    this.subscribers[event].push(callback)
  }
  unsubscribe(event, callback) {
    if (!this.subscribers[event]) {
      return
    }
    const index = this.subscribers[event].indexOf(callback)
    if (index !== -1) {
      this.subscribers[event].splice(index, 1)
    }
  }
  publish(event, ...args) {
    if (!this.subscribers[event]) {
      return
    }
    this.subscribers[event].forEach(fn => {
      fn.apply(this, args)
    })
  }
}

const eventBus = new EventBus()
const callback1 = () => console.log('callback1 is called')
const callback2 = () => console.log('callback2 is called')
eventBus.subscribe('test', callback1)
eventBus.subscribe('test', callback2)
eventBus.publish('test') // callback1 is called', 'callback2 is called'
eventBus.unsubscribe('test', callback1)
eventBus.publish('test') // 'callback2 is called'

三、发布订阅者模式实例代码

下面是一个发布订阅者模式的实例,我们模拟了一个购买商品的场景。当用户购买商品时,我们将触发一个名为“buy”事件,并传递商品名称和价格。购物车和订单模块可以订阅该事件,以便在用户购买商品时更新购物车和订单信息。

class EventBus {
  constructor() {
    this.subscribers = {}
  }
  subscribe(event, callback) {
    if (!this.subscribers[event]) {
      this.subscribers[event] = []
    }
    this.subscribers[event].push(callback)
  }
  unsubscribe(event, callback) {
    if (!this.subscribers[event]) {
      return
    }
    const index = this.subscribers[event].indexOf(callback)
    if (index !== -1) {
      this.subscribers[event].splice(index, 1)
    }
  }
  publish(event, ...args) {
    if (!this.subscribers[event]) {
      return
    }
    this.subscribers[event].forEach(fn => {
      fn.apply(this, args)
    })
  }
}

const eventBus = new EventBus()

class Cart {
  constructor() {
    this.items = []
    eventBus.subscribe('buy', this.add.bind(this))
  }
  add(item) {
    this.items.push(item)
    console.log(`Item ${item.name} is added to the cart`)
  }
}
class Order {
  constructor() {
    this.items = []
    eventBus.subscribe('buy', this.add.bind(this))
  }
  add(item) {
    this.items.push(item)
    console.log(`Item ${item.name} is added to the order`)
  }
}

const cart = new Cart()
const order = new Order()

eventBus.publish('buy', { name: 'iPhone', price: '999' })
// 'Item iPhone is added to the cart', 'Item iPhone is added to the order'

四、发布订阅者模式怎么理解

发布订阅者模式是一种解耦的方式,将生产者和消费者完全解耦,使得它们之间没有直接的依赖关系。生产者和消费者之间仅仅通过一个中间件来通信。生产者将消息发布到中间件中,而消费者则从中间件中订阅消息。这种解耦方式使得系统变得更加松散,更容易扩展和维护。

发布者订阅者模式可以应用于很多地方,比如事件机制、消息队列、Redux等。在Vue.js中,也使用了类似的机制来实现组件间的通信,将组件间的通信从父子关系中解耦出来,使得组件之间具有更高的可扩展性和复用性。

五、发布订阅者模式面试题

以下是一些与发布订阅者模式相关的面试题:

1、请说出发布订阅者模式和观察者模式的区别。

答:在发布订阅者模式中,发布者和订阅者之间没有直接的联系,而是通过一个中间件来进行通信。而在观察者模式中,观察者对象需要直接订阅主题对象。

2、请说出事件机制的实现方式。

答:事件机制本质上就是一种发布订阅者模式的实现。我们可以为一个事件注册回调函数,当这个事件触发时,所有注册的回调函数都会被依次调用。

六、发布订阅者模式的实现

下面是一个基于ES6的发布订阅者模式的实现:

class EventBus {
  constructor() {
    this.subscribers = new Map()
  }
  subscribe(event, callback) {
    if (!this.subscribers.has(event)) {
      this.subscribers.set(event, [])
    }
    this.subscribers.get(event).push(callback)
  }
  unsubscribe(event, callback) {
    if (!this.subscribers.has(event)) {
      return
    }
    const index = this.subscribers.get(event).indexOf(callback)
    if (index !== -1) {
      this.subscribers.get(event).splice(index, 1)
    }
  }
  publish(event, ...args) {
    if (!this.subscribers.has(event)) {
      return
    }
    this.subscribers.get(event).forEach(fn => {
      fn.apply(this, args)
    })
  }
}

const eventBus = new EventBus()
eventBus.subscribe('test', () => console.log('test is called'))
eventBus.publish('test') // 'test is called'
eventBus.unsubscribe('test') // remove all subscribers for 'test' event

七、发布订阅者模式在Vue中的应用

在Vue.js中,组件间的通信可以通过props传递数据、事件派发和监听等方式来实现。其中事件派发和监听的机制就是基于发布订阅者模式来实现的。当组件A需要向组件B发送事件时,它会使用$emit方法来触发一个名为event的事件,并传递参数值。而组件B则需要使用$on方法来注册这个事件,并在回调函数中处理参数值。

以下是一个在Vue中使用发布订阅者模式来进行组件通信的实例:

//Parent.vue
<template>
  <Child @eventName="handleEvent"></Child>
</template>
<script>
  import { EventBus } from '@/event-bus.js'
  export default {
    methods: {
      handleEvent() {
        // handle event here
      }
    },
    mounted() {
      EventBus.$on('eventName', this.handleEvent)
    },
    beforeDestroy() {
      EventBus.$off('eventName', this.handleEvent)
    }
  }
</script>

//Child.vue
<template>
  <button @click="sendEvent">Send Event</button>
</template>
<script>
  import { EventBus } from '@/event-bus.js'
  export default {
    methods: {
      sendEvent() {
        EventBus.$emit('eventName', data)
      }
    }
  }
</script>

//event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/235925.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-12 11:57
下一篇 2024-12-12 11:57

相关推荐

  • 手机安全模式怎么解除?

    安全模式是一种手机自身的保护模式,它会禁用第三方应用程序并使用仅限基本系统功能。但有时候,安全模式会使你无法使用手机上的一些重要功能。如果你想解除手机安全模式,可以尝试以下方法: …

    编程 2025-04-28
  • Qt State Machine与状态机模式

    本文将介绍Qt State Machine和状态机模式在Qt中的实现。Qt提供了QStateMachine和QState两个类,可以方便地实现状态机模式,并且能有效地处理复杂的、多…

    编程 2025-04-27
  • 显示C++设计模式

    本文将详细介绍显示C++设计模式的概念、类型、优点和代码实现。 一、概念 C++设计模式是在软件设计阶段定义,用于处理常见问题的可重用解决方案。这些解决方案是经过测试和验证的,并已…

    编程 2025-04-27
  • Centos7进入单用户模式的解释

    本文将介绍如何在Centos7中进入单用户模式,并从以下几个方面进行详细的阐述。 一、Centos7进入单用户模式的解答 在Centos7中进入单用户模式需要执行以下步骤: 1. …

    编程 2025-04-27
  • 深入解析PSM模式

    一、PSM模式是什么 PSM模式,即页面-状态-模型模式,是一种前端开发模式。它以页面为中心,将页面内的所有状态和业务逻辑抽象成一个由页面转化而来的虚拟状态机模型,从而将业务逻辑与…

    编程 2025-04-25
  • 授权码模式与OAuth2.0

    一、什么是授权码模式 授权码模式(Authorization Code Grant Type)是OAuth2.0协议中最常用的授权方式之一,也是最为安全的一种授权方式。授权码模式的…

    编程 2025-04-24
  • 谷歌浏览器深色模式

    一、深色模式的概念 深色模式是一种日益流行的 UI 设计趋势,通过使用暗灰色或黑色背景,大大降低了屏幕的亮度,更加舒适和护眼。深色模式也被称为暗黑模式。 谷歌浏览器深色模式的推出可…

    编程 2025-04-24
  • 暗黑模式的盛行

    一、背景和定义 暗黑模式起源于智能手表和夜视仪等专业设备上的配色方案,是指采用黑底白字、暗灰底白字等相对较暗的背景色搭配亮色前景,以减少屏幕对用户眼睛的刺激,降低视觉疲劳感。这种设…

    编程 2025-04-24
  • 从多个方面详细阐述MVC模式和三层架构

    一、MVC模式 MVC是Model-View-Controller的缩写,是一种应用于软件工程的设计模式。MVC模式将一个软件应用分为三个基本部分:模型(Model)、视图(Vie…

    编程 2025-04-24
  • 单例模式的作用

    一、概念解释 1、单例模式是指一个类只允许存在一个实例对象,且该对象能被系统中其他模块所共用。该模式主要解决了全局变量的问题,在同一时间只有一个实例被使用,避免了多次重复实例化造成…

    编程 2025-04-23

发表回复

登录后才能评论