当前位置: 首页 > news >正文

C++中的观察者模式

目录

观察者模式(Observer Pattern)

实际应用

股票价格监控系统

发布-订阅系统

总结


观察者模式(Observer Pattern)

观察者模式是一种行为型设计模式,它定义了对象间的一对多依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。观察者模式主要包含以下角色:
1. Subject(主题):保存对观察者的引用,并提供注册和注销观察者的方法。
2. Observer(观察者):定义一个更新接口,用于接收主题的通知。
3. ConcreteSubject(具体主题):具体实现主题,维护其状态并在状态改变时通知观察者。
4. ConcreteObserver(具体观察者):具体实现观察者,响应主题的通知并进行相应的更新。

实际应用

股票价格监控系统

-- 实现一个股票价格监控系统,当股票价格发生变化时,所有注册的观察者(例如投资者)都会收到通知。

#include <iostream>
#include <vector>
#include <string>
#include <memory>// 观察者接口
class Observer {
public:virtual void update(const std::string& stockName, float price) = 0;
};// 主题接口
class Subject {
public:virtual void registerObserver(std::shared_ptr<Observer> observer) = 0;virtual void removeObserver(std::shared_ptr<Observer> observer) = 0;virtual void notifyObservers() = 0;
};// 具体主题
class Stock : public Subject {
private:std::string name;float price;std::vector<std::shared_ptr<Observer>> observers;public:Stock(const std::string& name, float price) : name(name), price(price) {}void setPrice(float newPrice) {price = newPrice;notifyObservers();}float getPrice() const {return price;}void registerObserver(std::shared_ptr<Observer> observer) override {observers.push_back(observer);}void removeObserver(std::shared_ptr<Observer> observer) override {observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());}void notifyObservers() override {for (auto& observer : observers) {observer->update(name, price);}}
};// 具体观察者
class Investor : public Observer {
private:std::string name;public:Investor(const std::string& name) : name(name) {}void update(const std::string& stockName, float price) override {std::cout << "Investor " << name << " is notified that " << stockName << " price changed to " << price << std::endl;}
};// 客户端代码
int main() {auto stock = std::make_shared<Stock>("AAPL", 150.0);auto investor1 = std::make_shared<Investor>("Alice");auto investor2 = std::make_shared<Investor>("Bob");stock->registerObserver(investor1);stock->registerObserver(investor2);stock->setPrice(155.0);stock->setPrice(160.0);stock->removeObserver(investor1);stock->setPrice(165.0);return 0;
}

发布-订阅系统

-- 实现一个简单的发布-订阅系统,当发布者发布新消息时,所有订阅者都会收到通知。

#include <iostream>
#include <vector>
#include <string>
#include <memory>// 观察者接口
class Subscriber {
public:virtual void update(const std::string& message) = 0;
};// 主题接口
class Publisher {
public:virtual void registerSubscriber(std::shared_ptr<Subscriber> subscriber) = 0;virtual void removeSubscriber(std::shared_ptr<Subscriber> subscriber) = 0;virtual void notifySubscribers() = 0;
};// 具体主题
class NewsPublisher : public Publisher {
private:std::string latestNews;std::vector<std::shared_ptr<Subscriber>> subscribers;public:void publishNews(const std::string& news) {latestNews = news;notifySubscribers();}void registerSubscriber(std::shared_ptr<Subscriber> subscriber) override {subscribers.push_back(subscriber);}void removeSubscriber(std::shared_ptr<Subscriber> subscriber) override {subscribers.erase(std::remove(subscribers.begin(), subscribers.end(), subscriber), subscribers.end());}void notifySubscribers() override {for (auto& subscriber : subscribers) {subscriber->update(latestNews);}}
};// 具体观察者
class ConcreteSubscriber : public Subscriber {
private:std::string name;public:ConcreteSubscriber(const std::string& name) : name(name) {}void update(const std::string& message) override {std::cout << "Subscriber " << name << " received: " << message << std::endl;}
};// 客户端代码
int main() {auto publisher = std::make_shared<NewsPublisher>();auto subscriber1 = std::make_shared<ConcreteSubscriber>("Alice");auto subscriber2 = std::make_shared<ConcreteSubscriber>("Bob");publisher->registerSubscriber(subscriber1);publisher->registerSubscriber(subscriber2);publisher->publishNews("Breaking News: Observer Pattern in Action!");publisher->publishNews("Latest Update: New Design Patterns Discovered!");publisher->removeSubscriber(subscriber1);publisher->publishNews("Exclusive: Observer Pattern Simplified!");return 0;
}

总结

观察者模式帮助我们定义了对象间的一对多依赖关系,使得对象之间的通信变得更加灵活和可扩展。

相关文章:

C++中的观察者模式

目录 观察者模式&#xff08;Observer Pattern&#xff09; 实际应用 股票价格监控系统 发布-订阅系统 总结 观察者模式&#xff08;Observer Pattern&#xff09; 观察者模式是一种行为型设计模式&#xff0c;它定义了对象间的一对多依赖关系。当一个对象的状态发生改变…...

conda虚拟环境,安装pytorch cuda cudnn版本一致,最简单方式

1、pytorch版本安装&#xff08;卸载也会有问题&#xff09; &#xff08;1&#xff09;版本如何选择参考和卸载 https://zhuanlan.zhihu.com/p/401931724 &#xff08;2&#xff09;对应版本如何安装命令 https://pytorch.org/get-started/previous-versions/ 最简答安装参考…...

第 5 章:面向生产的 Spring Boot

在 4.1.2 节中&#xff0c;我们介绍了 Spring Boot 的四大核心组成部分&#xff0c;第 4 章主要介绍了其中的起步依赖与自动配置&#xff0c;本章将重点介绍 Spring Boot Actuator&#xff0c;包括如何通过 Actuator 提供的各种端点&#xff08;endpoint&#xff09;了解系统的…...

在 Windows 操作系统中,可以通过命令行工具来杀死进程

1. 使用 taskkill 命令 taskkill 命令是一个用于终止进程的命令行工具&#xff0c;可以通过进程名称或进程 ID (PID) 来杀死进程。 按进程名称杀死进程 taskkill /IM processname.exe /Fprocessname.exe 是进程的名称。/F 参数表示强制终止进程。 例如&#xff0c;终止名为…...

uni-app文件下载 h5 xls 乱码 锟斤拷 Blob pdf打不开

原先下载方式&#xff0c;PC管理端和浏览器打开文件能下载&#xff0c;xls没出现乱码&#xff0c;pdf能正常显示,H5下载xls乱码锟斤拷&#xff0c;PDF显示空白内容 怀疑是前端问题&#xff0c;也尝试过修改后端代码 后端设置编码格式 response.setCharacterEncoding(characte…...

Vue25-内置指令02:v-text指令

一、v-html对比v-text v-html支持结构的解析&#xff0c;v-text不支持结构的解析。 二、v-html的安全性问题 2-1、cookie的原理&#xff08;node.js&#xff09; 7天免登录&#xff0c;cookie实现。 cookie的本质就是类似于json的字符串&#xff0c;格式是&#xff1a;key-va…...

stable diffusion中的negative prompt是如何工作的

https://stable-diffusion-art.com/how-negative-prompt-work/https://stable-diffusion-art.com/how-negative-prompt-work/https://zhuanlan.zhihu.com/p/644879268...

STM32项目分享:智能小区充电桩系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.c…...

PDU模块中浪涌保护模块与空开模块的应用

由于PDU具体应用的特殊性&#xff0c;其在规划设计时具有应用场景的针对性&#xff0c;同时PDU的高度定制化的特点&#xff0c;是其他电气联接与保护产品所不具备的。 PDU基础的输出输入功能外&#xff0c;其电路的控制与电压保护器同时也极为重要。空气开关和浪涌保护器相关功…...

19、Go Gin框架集成Swagger

介绍&#xff1a; Swagger 支持在 Gin 路由中使用一系列注释来描述 API 的各个方面。以下是一些常用的 Swagger 注释属性&#xff0c;这些属性可以在 Gin 路由的注释中使用&#xff1a; Summary: 路由的简短摘要。Description: 路由的详细描述。Tags: 用于对路由进行分类的标…...

自动同步库数据——kettle开发36

kettle中的那些人工智能。 一、kettle的AI能力目录 跨库同步 2.自动开发 3.自动优化 二、AI实例 1、跨库同步 sqlsever表同步至oracle数据库 1.1源库sqlserver 1.2目标库oracle 1.3可视化跨库同步 使用多表复制向导 选择跨库的表&#xff0c;下一步下一步&#xff0c;即可…...

MSOCache在电脑中可以删除吗?

MSOCache文件夹在电脑中是可以删除的。但删除前需要了解以下几点&#xff1a; MSOCache文件夹的作用&#xff1a; MSOCache文件夹是Microsoft Office的本地安装源&#xff0c;用于存储Office安装和更新过程中所需的临时文件&#xff0c;如安装程序所需的组件、配置设置以及更新…...

数据网格和视图入门

WinForms数据网格&#xff08;GridControl类&#xff09;是一个数据感知控件&#xff0c;可以以各种格式&#xff08;视图&#xff09;显示数据。本主题包含以下部分&#xff0c;这些部分将指导您如何使用网格控件及其视图和列&#xff08;字段&#xff09;。 Grid Control’s…...

雨的轮回与生命的律动

雨的轮回与生命的律动 我们生活在一个充满变数的世界里&#xff0c;许多事情无法预测&#xff0c;如同这不知何时会停歇的雨。然而&#xff0c;尽管我们无法预知雨停的确切时刻&#xff0c;但我们深知&#xff0c;这场雨终将会过去&#xff0c;阳光终将再次洒满大地。这种对未…...

CANopen for Python 使用教程(二)

系列文章目录 前言 CANopen 标准的 Python 实现。该项目的目的是在一个简单的 Pythonic 接口中支持 CiA 301 标准中最常见的部分。它主要针对测试和自动化任务&#xff0c;而不是符合标准的主实施。 该库支持 Python 3.6 及以上版本。 一、特点 该库主要用作主库。 NMT 主站…...

前方碰撞缓解系统技术规范(简化版)

前方碰撞缓解系统技术规范(简化版) 1 系统概述2 工作时序3 预警目标4 功能条件5 HMI开关6 显示需求7 相关子功能8 TTC标定参考9 指标需求1 系统概述 前方碰撞缓解系统包含LW潜在危险报警、FCW前方碰撞预警和AEB自动紧急制动三个部分。 LW潜在危险报警:根据本车与前车保持的…...

数据赋能(117)——体系:数据收集——实施过程、应用特点

实施过程 数据收集过程是一个系统化、有序的步骤集合&#xff0c;旨在确保能够准确、高效地获取所需数据。以下是数据收集过程的基本步骤&#xff1a; 明确数据需求&#xff1a;这是数据收集的第一步&#xff0c;需要明确需要收集哪些类型的数据&#xff0c;这些数据将如何支…...

【吃包子game】

如果您想要编写一个简单的“吃包子”游戏代码&#xff0c;可以使用Python语言来实现。下面是一个简单的例子&#xff0c;该游戏会随机生成一定数量的包子&#xff0c;玩家每次可以吃掉一个包子&#xff0c;直到包子被吃光为止。 import random def eat_dumplings():# 随机生成…...

图片转Base64

在Python中, 可以使用内置的base64模块以及图像处理库(如PIL, 也称为Pillow)来将图片转换为Base64编码的字符串. 以下是一个简单的示例, 说明如何实现这一过程:首先, 需要安装Pillow库(如果尚未安装), 可以使用pip来安装: pip install pillow然后, 可以使用以下Python代码将图片…...

STM32项目分享:智能家居语音系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB打板焊接图: 五、程序设计 六、实验效果 七、包含内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.com…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解

文章目录 一、开启慢查询日志&#xff0c;定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...