设计模式—观察者模式(发布-订阅模式)

一、简介

发布-订阅模式是一种消息传递模式,用于实现对象间的一对多依赖关系。在这种模式中:

  • 发布者(Publisher)不直接向订阅者(Subscriber)发送消息
  • 发布者和订阅者通过一个中介(通常称为事件总线或消息代理)进行通信
  • 订阅者可以订阅感兴趣的事件,发布者可以发布事件

这种模式实现了发布者和订阅者的解耦,提高了系统的灵活性和可扩展性。

二、原理

2.1核心组件

Publisher(发布者):产生事件/消息的对象

Subscriber(订阅者):接收并处理事件的对象

Event Bus/Message Broker(事件总线):管理订阅关系,负责将消息从发布者路由到订阅者

2.2工作流程

订阅者向事件总线注册对特定事件的兴趣

发布者向事件总线发布事件

事件总线将事件传递给所有注册的订阅者

三、C++实现

以下是发布-订阅模式的简单C++实现:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <functional>
#include <memory>// 前置声明
class EventBus;// 订阅者接口
class Subscriber {
public:virtual ~Subscriber() = default;virtual void handleEvent(const std::string& event, const std::string& message) = 0;
};// 具体订阅者
class ConcreteSubscriber : public Subscriber {
public:ConcreteSubscriber(const std::string& name) : name_(name) {}void handleEvent(const std::string& event, const std::string& message) override {std::cout << name_ << " received event '" << event << "' with message: " << message << std::endl;}private:std::string name_;
};// 事件总线
class EventBus {
public:// 订阅事件void subscribe(const std::string& event, Subscriber* subscriber) {subscribers_[event].push_back(subscriber);}// 取消订阅void unsubscribe(const std::string& event, Subscriber* subscriber) {auto& subs = subscribers_[event];subs.erase(std::remove(subs.begin(), subs.end(), subscriber), subs.end());}// 发布事件void publish(const std::string& event, const std::string& message) {if (subscribers_.find(event) != subscribers_.end()) {for (auto subscriber : subscribers_[event]) {subscriber->handleEvent(event, message);}}}private:std::map<std::string, std::vector<Subscriber*>> subscribers_;
};// 发布者
class Publisher {
public:Publisher(EventBus& eventBus) : eventBus_(eventBus) {}void publish(const std::string& event, const std::string& message) {eventBus_.publish(event, message);}private:EventBus& eventBus_;
};int main() {EventBus eventBus;// 创建订阅者ConcreteSubscriber sub1("Subscriber1");ConcreteSubscriber sub2("Subscriber2");ConcreteSubscriber sub3("Subscriber3");// 订阅事件eventBus.subscribe("event1", &sub1);eventBus.subscribe("event1", &sub2);eventBus.subscribe("event2", &sub2);eventBus.subscribe("event2", &sub3);// 创建发布者Publisher publisher(eventBus);// 发布事件publisher.publish("event1", "First event message");publisher.publish("event2", "Second event message");// 取消订阅eventBus.unsubscribe("event1", &sub2);// 再次发布publisher.publish("event1", "Event after unsubscribe");return 0;
}

代码运行结果:

微信截图_20250706152914

四、应用场景

  1. GUI系统中的事件处理
  2. 分布式系统中的消息传递
  3. 微服务架构中的服务间通信
  4. 游戏开发中的事件系统
  5. 日志系统和监控系统

优点

  1. 松耦合:发布者和订阅者不需要知道对方的存在
  2. 可扩展性:可以轻松添加新的发布者或订阅者
  3. 灵活性:订阅者可以动态订阅或取消订阅事件

缺点

  1. 调试困难:由于间接性,事件流可能难以跟踪
  2. 性能开销:消息传递可能比直接调用慢
  3. 可能导致内存泄漏:如果订阅者没有正确取消订阅

发布-订阅模式是现代软件架构中非常重要的模式,特别是在需要组件间松散耦合的系统中。

参考文章:

1.“牵一发而动全身”——我用观察者模式简单模拟吃鸡

2.《推荐C++ 23种设计模式》系列第十九期:观察者模式【架构设计与实现】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913522.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913522.shtml
英文地址,请注明出处:http://en.pswp.cn/news/913522.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文讲清楚React Fiber

文章目录一文讲清楚React Fiber1. 基础概念1.1浏览器刷新率&#xff08;帧&#xff09;1.2 JS执行栈1.3 时间分片1.4 链表2. React Fiber是如何实现更新过程控制2.1 任务拆分2.2挂起、恢复、终止2.2.1 挂起2.2.2 恢复2.2.3 终止2.3 任务具备优先级一文讲清楚React Fiber 1. 基…

(3)机器学习小白入门 YOLOv: 解锁图片分类新技能

(1)机器学习小白入门YOLOv &#xff1a;从概念到实践 (2)机器学习小白入门 YOLOv&#xff1a;从模块优化到工程部署 (3)机器学习小白入门 YOLOv&#xff1a; 解锁图片分类新技能 前言 YOLOv 算法通常被用于目标检测任务&#xff0c;但通过对其进行适当的调整和改造&#xff0c…

主机安全-开源HIDS字节跳动Elkeid使用

安装好elkeid后就开始接入主机和k8s集群&#xff0c;安装文档-----主机安全-开源HIDS字节跳动Elkeid安装-CSDN博客 1、接入主机 在系统管理-----安装配置-----复制命令------在目标机器上执行这段命令 执行成功后主机就会自动接入 2、接入k8s集群 在k8s主机上执行脚本&#x…

【vue】用conda配置nodejs,一键开通模版使用权

特此鸣谢我的好同学重中之重的特级教学&#xff0c;非常之好用一、conda环境下载安装二、创建包含nodejs的conda环境创建一个新环境&#xff1a;conda create -n 【自定义环境名字】 python3.9 conda create -n my_nodejs_env python3.9激活新环境&#xff1a;conda activate【…

深度学习--tensor(创建、属性)

一、torch概念1.1简介pytorch简称torch&#xff0c;意为深度学习框架。它使用张量&#xff08;tensor&#xff09;来表示数据&#xff0c;可以轻松地处理大规模数据集&#xff0c;且可以在GPU上加速。pytorch基本功能&#xff1a;自动微分、自动求导等。1.2安装官网获得下载命令…

【内存】Linux 内核优化实战 - net.ipv4.tcp_max_tw_buckets

目录net.ipv4.tcp_max_tw_buckets 详解一、基本概念二、核心作用三、默认值四、调整场景需增大参数的场景需减小参数的场景五、查看与修改方法1. 查看当前值2. 临时修改&#xff08;重启失效&#xff09;3. 永久修改&#xff08;重启生效&#xff09;六、注意事项总结net.ipv4.…

短剧系统开发定制全流程解析:从需求分析到上线运营

一、短剧行业现状与系统开发价值短剧作为一种新兴的内容形态&#xff0c;近年来呈现爆发式增长态势。2023年中国短剧市场规模已突破300亿元&#xff0c;用户规模超过5亿&#xff0c;这种以"快节奏、强剧情、低成本"为特点的内容形式正在重塑数字娱乐产业格局。短剧系…

各服务器厂商调整BIOS睿频教程

调整BIOS睿频选项汇总&#xff1a;1、华为服务器&#xff1a;2、华为服务器V53、浪潮服务器4、浪潮服务器M45、 曙光服务器5.1 曙光I620-G205.2 曙光I620-G306、联想服务器&#xff08;650系列&#xff09;650系列的服务器对照截图信息修改对应项&#xff0c;修改为截图里的选项…

PyTorch笔记3----------统计学相关函数

1.基础函数 import torch a torch.rand(2,2) print("a:\n",a) print(########################) print("平均值:\n",torch.mean(a,dim0)) print("总和:\n",torch.sum(a,dim0)) print("所有元素的积:\n",torch.prod(a,dim0)) print(&…

【Prometheus】通过tar包部署单机版Prometheus 和 Pushgateway

在ECS&#xff08;Elastic Compute Service&#xff09;机器上通过tar包部署 Prometheus 和 Pushgateway&#xff0c;并配置 Prometheus 采集 Pushgateway 的数据&#xff0c;是一个常见的监控部署任务。以下是详细的步骤说明&#xff1a;&#x1f9e9; 环境准备 操作系统&…

Matlab 频谱分析 (Spectral Analysis)

文章目录1. 信号预处理 - 去直流分量2. 快速傅里叶变换&#xff08;FFT&#xff09;3. 功率谱密度&#xff08;PSD&#xff09;计算4. 主频率检测5. 谱质心计算6. 对数谱显示完整的信号处理流程实际应用示例1. 信号预处理 - 去直流分量 data data - mean(data);数学原理&…

【实时Linux实战系列】实时以太网与 TSN 基础

在实时系统中&#xff0c;网络通信的实时性和可靠性是确保系统正常运行的关键。实时以太网和时间敏感网络&#xff08;TSN&#xff09;技术为实时数据传输提供了强大的支持。TSN通过一系列协议和机制&#xff0c;确保数据能够在预定的时间内可靠传输&#xff0c;满足工业自动化…

茶颜悦色JAVA面试分享

1、自我介绍项目2、设计一个爆款饮品秒杀系统&#xff1a;如何解决“幽兰拿铁”上新时的瞬时10万QPS&#xff1f;从缓存、限流、库存扣减到订单创建的全流程设计。3、订单超市未支付自动取消&#xff1a;如何实现高精度&#xff08;30分钟精确到秒&#xff09;且低延迟的订单状…

OneCode图表配置速查手册

前言 在数据可视化日益成为业务决策核心驱动力的今天&#xff0c;高效、灵活的图表配置系统已成为开发人员不可或缺的工具。OneCode图表组件凭借其丰富的图表类型与精细化的配置能力&#xff0c;为开发者提供了构建专业数据可视化界面的完整解决方案。然而&#xff0c;随着图表…

二维码驱动的独立站视频集成方案

一、独立站视频嵌入的技术挑战与架构设计 在独立站建设中&#xff0c;视频内容的集成面临着性能、安全与用户体验的三重挑战。传统直接嵌入方式会导致页面加载缓慢&#xff08;平均增加3-5秒首屏时间&#xff09;、服务器带宽消耗激增&#xff08;单视频日均播放1000次约产生50…

【STM32】预分频因子(Prescaler)和重装载值(Reload Value)

在 STM32 的 独立看门狗&#xff08;IWDG&#xff09; 中&#xff08;结合上文【STM32】独立看门狗&#xff08;提供完整实例代码&#xff09;&#xff09;&#xff0c;为了控制看门狗的超时时间&#xff08;溢出时间&#xff09;&#xff0c;我们主要设置两个参数&#xff1a;…

从0到1搭建同城O2O外卖平台:外卖系统源码架构解析与实战指南

当下&#xff0c;越来越多的创业者、品牌连锁商家&#xff0c;甚至社区集群&#xff0c;开始布局属于自己的本地外卖平台。而对于软件开发者和技术团队而言&#xff0c;如何从0到1搭建一套可落地、可扩展、可持续运营的外卖系统&#xff0c;成为了一个既现实又挑战性十足的话题…

MySQL 8.0 OCP 1Z0-908 题目解析(16)

题目61 Choose the best answer. Examine this command, which executes successfully: mysqlbackup --defaults-file/backups/server-my.cnf --backup-dir/backups/full copy-backWhich statement is true about the copy-back process? ○ A) It restores files from the da…

WSL命令

以下是 WSL&#xff08;Windows Subsystem for Linux&#xff09;的常用命令大全&#xff0c;涵盖安装、管理、网络、文件交互等场景&#xff0c;方便快速查阅和使用&#xff1a;1. 安装与版本管理命令说明wsl --install默认安装 WSL 和 Ubuntuwsl --install -d <发行版名&g…

AI语音训练——GPT-SoVITS(GSV)

链接说明 github项目地址&#xff1a;RVC-Boss/GPT-SoVITS: 1 min voice data can also be used to train a good TTS model! (few shot voice cloning) 项目中文说明书&#xff1a; GPT-SoVITS指南//项目说明书里也有在线使用的链接 原项目作者B站教学视频&#xff1a;耗时两个…