發布訂閱者模式

一、發布訂閱者模式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/zh-hant/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

發表回復

登錄後才能評論