觀察者模式(Observer Pattern)和 發布-訂閱模式(Publisher-Subscriber Pattern)

你對 觀察者模式(Observer Pattern)和 發布-訂閱模式(Publisher-Subscriber Pattern)的描述是非常準確的,并且闡明了它們的核心區別。為了幫助你更好地理解這兩者的細微差異,下面是一個更詳細的對比分析:

1. 觀察者模式(Observer Pattern)

概念:

  • 觀察者模式是一種 行為型設計模式,用于定義對象之間一對多的依賴關系。當一個對象的狀態發生變化時,所有依賴于它的對象都會自動更新。通常,這些依賴對象被稱為“觀察者”。

工作流程:

  1. 主題(Subject):發布事件的對象。當主題的狀態發生變化時,它會通知所有已注冊的觀察者。
  2. 觀察者(Observer):訂閱主題的對象。當主題狀態變化時,觀察者會收到通知并執行相關的操作。

實現方式:

  • 觀察者模式通常沒有中介,觀察者直接訂閱主題(即,主題直接管理觀察者)。當主題的狀態發生變化時,主題會直接通知所有已注冊的觀察者。

應用場景:

  • UI 更新:在前端開發中,通常有多個視圖組件需要更新。例如,React 和 Vue 中的響應式數據綁定就是基于觀察者模式來實現的。
  • 事件處理:瀏覽器中的 DOM 事件模型(如 click, hover 等)也采用了觀察者模式。

代碼示例(JavaScript)

// 主題
class Subject {constructor() {this.observers = [];}// 注冊觀察者subscribe(observer) {this.observers.push(observer);}// 通知觀察者notify() {this.observers.forEach(observer => observer.update());}
}// 觀察者
class Observer {update() {console.log('State has been updated');}
}const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();subject.subscribe(observer1);
subject.subscribe(observer2);subject.notify();  // 輸出 "State has been updated" 兩次

特點:

  • 緊密耦合:觀察者直接與主題連接,主題必須管理所有觀察者的訂閱和通知。
  • 同步通知:當主題狀態變化時,所有觀察者都會同步地被通知。

2. 發布-訂閱模式(Publisher-Subscriber Pattern)

概念:

  • 發布-訂閱模式也是一種 行為型設計模式,它允許發布者和訂閱者之間解耦。發布者發布消息,訂閱者訂閱感興趣的消息。在該模式下,發布者和訂閱者沒有直接的依賴關系,它們通過 中介(事件總線、消息調度中心) 進行通信。

工作流程:

  1. 發布者(Publisher):發布消息的對象。它發布某種類型的事件或消息,但不需要知道誰會接收這些消息。
  2. 訂閱者(Subscriber):訂閱消息的對象。它將自己感興趣的事件注冊到調度中心(事件總線),并在事件發布時接收通知。
  3. 調度中心(Event Channel / Event Bus):事件的中介,負責接收消息并將它們分發到所有訂閱了該消息的訂閱者。

實現方式:

  • 發布-訂閱模式通過中介來解耦發布者和訂閱者,通常采用 事件總線消息隊列 來處理事件的注冊和分發。當某個事件發生時,調度中心會通知所有相關的訂閱者。

應用場景:

  • 前端框架的事件系統:如 Vue.js 的事件系統和 React 中的狀態管理。
  • 微服務架構:多個服務之間的消息通信通常采用發布-訂閱模式,確保服務之間松耦合。

代碼示例(JavaScript)

class EventBus {constructor() {this.events = {};}// 訂閱事件subscribe(event, callback) {if (!this.events[event]) {this.events[event] = [];}this.events[event].push(callback);}// 發布事件publish(event, data) {if (this.events[event]) {this.events[event].forEach(callback => callback(data));}}// 注銷訂閱unsubscribe(event, callback) {if (this.events[event]) {this.events[event] = this.events[event].filter(cb => cb !== callback);}}
}const eventBus = new EventBus();// 訂閱事件
eventBus.subscribe('dataReceived', (data) => {console.log('Received data:', data);
});// 發布事件
eventBus.publish('dataReceived', { message: 'Hello World' });// 注銷訂閱
eventBus.unsubscribe('dataReceived', (data) => {console.log('Received data:', data);
});

特點:

  • 松散耦合:發布者和訂閱者之間沒有直接依賴關系,所有的交互通過事件總線進行。
  • 異步通知:訂閱者接收到消息的方式通常是異步的。

關鍵區別:

特性觀察者模式發布-訂閱模式
依賴關系觀察者直接訂閱主題。主題管理觀察者。發布者和訂閱者通過中介(事件總線)進行通信,發布者和訂閱者互不直接依賴。
解耦程度觀察者和主題之間的耦合較高,主題負責管理所有觀察者。高度解耦,訂閱者與發布者通過事件總線等中介通信。
通知方式通常是同步通知。通常是異步通知。
使用場景適用于需要狀態通知、更新界面的場景,如 UI 更新。適用于事件驅動的系統,尤其是在微服務或消息隊列中常見。
復雜度簡單,通常由一個主題直接管理觀察者。需要一個中介(事件總線),更適用于較為復雜的系統。
事件的處理方式觀察者直接與主題互動。訂閱者通過中介接收和處理消息。

總結

  • 觀察者模式 強調的是一對多的直接依賴關系,主要用于更新界面或執行某些操作。
  • 發布-訂閱模式 提供了更高的靈活性和解耦,適用于更復雜的系統,其中發布者和訂閱者不直接依賴,而是通過中介進行事件的傳遞。

根據應用的復雜度和系統的需求,選擇合適的模式可以有效提高系統的靈活性和可維護性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90892.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90892.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90892.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025年接口技術的十字路口:當MCP遇見REST、GraphQL與gRPC

在當今這個由數據驅動、萬物互聯的時代,應用程序接口(API)已成為現代軟件架構的基石。它們是不同服務之間溝通的橋梁,支撐著從網頁應用到復雜的微服務生態系統的一切。長久以來,開發者們在REST、GraphQL和gRPC這幾種主…

【CTF-WEB-反序列化】利用__toString魔術方法讀取flag.php

題目 頁面提示輸入?code,那我們在網址里get一下出現了新頁面的提示,進入看看下面有個help.php頁面的提示,進入看看有一段php代碼,仔細分析,應該是要用反序列法代碼如下 class FileClass{ public $filename error.log…

在 github.com 與 sourceforge.net 上創建免費個人靜態網站、博客的區別

github.com github 屬于 git 版本管理專業網站,有免費和收費兩種套餐。git 的數據是存放在數據庫中的,要將數據庫中的數據顯示為網站的網頁,這需要服務器端提供專門的中間件支持才能實現。 特點: 官方支持:提供長期…

jenkins 入門指南:從安裝到啟動的完整教程

jenkins 入門指南:從安裝到啟動的完整教程 持續集成(CI)是現代開發流程中的核心環節,而 Jenkins 作為一款開源的 CI 工具,憑借簡單安裝、開箱即用、插件豐富、易于擴展等優勢,成為開發者的首選工具。它能自…

機器學習(重學版)基礎篇(概念與評估)

本篇參考周志華老師的西瓜書,但是本人學識有限僅能理解皮毛,如有錯誤誠請讀友評論區指正,萬分感謝。一、基礎概念與評估方法本節目標:建立理論基礎框架?1、機器學習定義機器學習是一門通過計算手段利用經驗(以數據形式…

spring/springboot SPI(二)配合使用的接口

spring.factories 里,Spring 會根據接口來加載實現類,常見的幾個接口包括:一、org.springframework.context.ApplicationListener1、作用監聽 Spring 容器事件,如 ApplicationReadyEvent。2、使用方法項目結構Spring Boot 2.xSpri…

基于Zig語言,opencv相關的c++程序靜態交叉編譯

一、寫在前面 1.什么是zig? Zig 是一種通用編程語言; Zig 最初的定位就是代替C語言的系統級語言,它提供了與 C 語言幾乎 100% 兼容(可直接調用 C 頭文件、鏈接 C 庫),同時不需要任何依賴構建系統。 Zig 同時附帶一…

基于 LSTM 與 SVM 融合的時間序列預測模型:理論框架與協同機制—實踐算法(1)

目錄 1、單一模型的局限性:混合架構的設計動機 2、LSTM 的時序特征提取:從原始序列到高階表征 2.1、門控機制的時序過濾能力 2.2、隱藏狀態的特征壓縮作用 2.3、預訓練的特征優化邏輯 3、SVM 的非線性映射:從高階特征到預測輸出 3.1、…

如何查看docker實例是否掛載目錄,以及掛載了哪些目錄

一條命令即可一次性列出當前容器里所有掛載點&#xff1a; docker inspect <容器ID或名稱> --format{{range .Mounts}}{{printf "%-8s %-35s -> %s\n" .Type .Source .Destination}}{{end}}示例輸出&#xff1a; bind /host/owrt/src …

Opentrons 模塊化平臺與AI技術助力智能移液創新,賦能AAW?自動化工作站

在生命科學領域加速擁抱自動化的關鍵節點&#xff0c;全球開源實驗室自動化領導者 Opentrons 攜手全球領先生命科學公司默克生命科學&#xff0c;重磅推出 AAW?智能自動化液體處理平臺。這一戰略合作的核心技術引擎 ——Opentrons Flex 第三代全自動移液工作站&#xff0c;正以…

C++學習筆記(八:函數與變量)

往篇內容&#xff1a; C學習筆記&#xff08;一&#xff09; 一、C編譯階段※ 二、入門案例解析 三、命名空間詳解 四、C程序結構 C學習筆記&#xff08;二&#xff09; 五、函數基礎 六、標識符 七、數據類型 補充&#xff1a;二進制相關的概念 sizeof 運算符簡介 補…

智慧施工:施工流程可視化管理系統

圖撲智慧施工全流程可視化管理系統&#xff0c;通過可視化界面&#xff0c;可直觀掌握各工序銜接進度、資源調配情況&#xff0c;快速識別違規作業、設備故障等風險點 —— 如塔吊運行半徑重疊、深基坑支護位移預警等。同時&#xff0c;系統支持施工方案模擬推演&#xff0c;對…

單鏈表的冒泡排序實現:從原理到代碼詳解

單鏈表的冒泡排序實現&#xff1a;從原理到代碼詳解 引言 單鏈表作為一種常見的數據結構&#xff0c;其排序操作因節點無法隨機訪問&#xff08;需通過指針遍歷&#xff09;而與數組排序存在差異。冒泡排序因其實現簡單、無需額外空間&#xff08;僅需指針操作&#xff09;&…

如何在 Ubuntu 24.04 或 22.04 上安裝和使用 GDebi

APT 是 Ubuntu 上安裝需要外部依賴項的 Debian 包的一種方式,但還有另一種選擇,即 GDebi。本文將介紹如何在 Ubuntu 24.04 上安裝 GDebi,以及如何使用它來安裝 .deb 包所需的依賴項。 什么是 GDebi? GDebi 是默認的 .deb 包安裝器 DPKG 的輕量級替代品。與 DPKG 不同,GD…

俄羅斯方塊游戲開發(面向對象編程)

摘要本設計基于MATLAB面向對象編程技術&#xff0c;開發了一款具備完整游戲邏輯的俄羅斯方塊游戲。通過類封裝實現游戲核心模塊&#xff08;方塊管理、游戲板狀態、碰撞檢測等&#xff09;&#xff0c;采用旋轉矩陣實現方塊變形&#xff0c;結合MATLAB圖形用戶界面&#xff08;…

背包DP之多重背包

背包DP之多重背包一、多重背包基礎認知1.1 問題定義1.2 核心特征二、基礎解法&#xff1a;暴力拆分2.1 核心思路2.2 代碼實現2.3 局限性分析三、優化解法&#xff1a;二進制拆分3.1 優化原理3.2 拆分步驟3.3 代碼實現3.4 復雜度分析四、二進制拆分過程五、多重背包的變種與應用…

Ansible 變量指南:聲明、優先級、作用域與最佳實踐(一)

Ansible 變量的聲明 前言 全面理解 Ansible 變量是編寫高效、可維護 Playbook 的關鍵。由于最近使用 Ansible 比較多&#xff0c;在變量問題上踩了不少坑&#xff0c;也因此對變量的聲明&#xff0c;優先級和作用域有了更深的理解。姑且總結一下&#xff0c;分享給大家&#…

[極客大挑戰 2019]FinalSQL--布爾盲注

直接看題可以看到題目給了提示盲注&#xff01;那么接下來就是尋找注入點了&#xff01;那么不能發現注入點就是id了&#xff01;注入類型為數值型注入&#xff01;這里直接嘗試盲注。但是這里and被過濾了&&也不行。問了幾個師傅說用or&#xff0c;但是空格被過濾了&am…

再談fpga開發(狀態機的應用)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】前面說過&#xff0c;fpga上面最基礎的部分是寄存器&#xff0c;而所有寄存器存在每一個clock下&#xff0c;都有被翻轉的可能性。至于這些寄存器是…

TCP如何解決網絡切換問題

一、傳統TCP的網絡切換問題核心問題&#xff1a;TCP 連接基于四元組&#xff08;源IP、源端口、目的IP、目的端口&#xff09;&#xff0c;IP 變化導致連接失效二、改進方案與技術演進1. MPTCP&#xff08;多路徑TCP&#xff09; - 主流解決方案核心機制&#xff1a;單連接多路…