观察者模式-C++

观察者模式(Observer)是一种行为型设计模式,它用于在对象之间建立一对多的依赖关系,当一个对象发生改变时,所有依赖它的对象都会收到通知进行相应的改变。

观察者模式中有两种核心角色:

  • 观察者(Observer):也被称为订阅者或监听者,观察者通过注册到特定的主题上,当主题的状态发生改变时,它可以收到这种变化更新自身状态。观察者定义了一个统一的接口,使得主题可以通过接口将通知发送给所有的观察者。
  • 主题(Subject):也称为被观察者,它管理着一组观察者对象,提供添加、删除观察者对象的方法。当主题发生改变的时候可以将通知发送给所有的观察者对象。

在这里面,观察者依赖主题,所以一个主题可以对应多个观察者。

观察者模式的流程:

  • 主题对象管理观察者对象的添加和删除
  • 主题对象维护一个观察者对象的列表,用于记录所有注册的观察者对象
  • 当主题对象的状态发生改变时,遍历观察者列表,将通知发送给每一个观察者对象
  • 观察者对象收到通知后更新自身的状态

观察者模式也有三个组件:观察者接口、观察者、主题

举例:
假设现在我们有一个电子商务平台,当用户下单之后我们希望通知库存系统和用户通知系统。

现在我们按照观察者模式的三个组件来编写代码:观察者接口、观察者、主题

// 观察者接口
class IObserver
{
public:virtual ~IObserver(){}virtual void Update(const std::string& _msg) = 0;
};// 观察者-库存系统
class InventorySystem: public IObserver
{
public:virtual void Update(const std::string& _msg) override{std::cout << "库存系统:" << _msg << std::endl;}
};// 观察者-用户通知系统
class UserNotifySystem: public IObserver
{
public:virtual void Update(const std::string& _msg) override{std::cout << "用户通知系统:" << _msg << std::endl;}
};// 主题
class Subject
{
public:// 添加观察者对象void AddObserver(std::shared_ptr<IObserver> _observer){if (_observer)observers_.push_back(_observer);}// 删除观察者对象void RemoveObserver(std::shared_ptr<IObserver> _observer){for (auto it = observers_.begin(); it != observers_.end();){if (*it == _observer)it = observers_.erase(it);elseit++;}}// 用户下单void UserPlatform(const std::string& _msg){std::cout << "用户下单:" << _msg << std::endl;NotifyAllObserver(_msg);}private:// 通知所有的观察者对象void NotifyAllObserver(const std::string _msg){for (auto it : observers_)it->Update(_msg);}private:// 记录所有注册的观察者对象std::list<std::shared_ptr<IObserver>> observers_;
};

在main.cpp里使用它:

void TestObserver()
{// 主题对象std::shared_ptr<Subject> subject = std::make_shared<Subject>();// 观察者对象-库存系统std::shared_ptr<IObserver> inventory_system = std::make_shared<InventorySystem>();// 观察者对象-用户通知系统std::shared_ptr<IObserver> user_notify = std::make_shared<UserNotifySystem>();// 注册观察者subject->AddObserver(inventory_system);subject->AddObserver(user_notify);// 用户下单subject->UserPlatform("iphone 11");std::cout << "---------------------删除 用户通知系统------------------" << std::endl;// 删除观察者subject->RemoveObserver(user_notify);// 用户下单subject->UserPlatform("小米 11");
}int main()
{// 策略模式用法// TestStrategy();TestObserver();system("pause");return 0;
}

输出:
在这里插入图片描述优点:

  • 松耦合:主题和观察者之间是松耦合的,修改一个观察者对象不影响其他对象
  • 可扩展:可以在任何时候添加和删除观察者,无需修改已有代码
  • 即时通知:一旦主题发生改变,观察者可以立即收到通知。

适用场景:

  • 当一个对象发生改变时,希望主动通知其他对象而不是其他对象等待通知时
  • 当具有一对多的关系时,一个对象的更新会影响到其他对象时

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

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

相关文章

ARPG----C++学习记录05 Section10 碰撞,重叠事件

collision碰撞 Query only 仅查询。包括请求&#xff0c;扫描和重叠&#xff0c;扫描两个物体知否存在重叠Physics Only 仅物理。重力&#xff0c;反弹等物理计算都开启 按下“~”输入show collision可以查看碰撞 给石块添加碰撞&#xff0c;Query可以阻挡人物过去&#xff0c;…

基于 HarmonyOS 的 HTTPS 请求过程开发示例(ArkTS)

介绍 本篇 Codelab 基于网络模块以及 Webview 实现一次 HTTPS 请求&#xff0c;并对其过程进行抓包分析。效果如图所示&#xff1a; 相关概念 ● Webview&#xff1a;提供 Web 控制能力&#xff0c;Web 组件提供网页显示能力。 ● HTTP数据请求&#xff1a;网络管理模块&am…

SparkAi创作系统ChatGPT网站源码+详细搭建部署教程+AI绘画系统+支持GPT4.0+Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

减轻关键基础设施网络安全风险的 3 种方法

物理安全和网络安全之间存在相当大的重叠&#xff0c;特别是在保护关键基础设施方面。防止基础设施被篡改需要在物理安全方面进行大量投资&#xff0c;但任何连接到互联网的设备都代表着更广泛网络的潜在攻击点。 缺乏足够保护的设备可能会给这些对手在网络中提供立足点&#…

UITableView的style是UITableViewStyleGrouped

一般情况下&#xff0c;UITableViewStylePlain和UITableViewStyleGrouped是UITableView常用到的style&#xff0c; 之前都是用到的时候&#xff0c;遇到问题直接用度娘&#xff0c;差不多就够用了&#xff0c;今天在修复UI提出的间隙问题&#xff0c;来回改&#xff0c;总觉得…

通过postgis空间库导入sql格式的矢量数据到arcgis中

1、在postgis中创建数据库 命名为test3 2、创建空间扩展 3、导入sql矢量文件 进入psql.exe目录中 进入dos命令框中 输入命令,其中host输入自己的主机ip,database为自己的数据库名称,数据路径修改为自己电脑上的路径,注意反斜杠 psql

企业计算机服务器中了halo勒索病毒怎么办,halo勒索病毒解密数据恢复

随着科技技术的不断提升&#xff0c;越来越多的企业开始走向数字化办公&#xff0c;让企业的生产运营得到了快速发展&#xff0c;但随之而来的网络安全威胁引起了人们的重视&#xff0c;近期&#xff0c;云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器…

双编码器构建机器人零力拖动/导纳控制思路

前言 这篇博客主要记录昨日与实验室大佬针对UR5机器人拖动示教功能实现的思路。由于本人并非主攻力控方面。直到昨天在做实验的时候&#xff0c;与力控组的大佬讨论过后才了解UR机器人实现导纳控制的思路。 关于导纳控制/零力拖动 导纳控制与阻抗控制单从字面去理解很容易记…

【赠书第3期】用ChatGPT轻松玩转机器学习与深度学习

文章目录 前言 1 机器学习 2 深度学习 3 使用ChatGPT进行机器学习和深度学习 4 推荐图书 5 粉丝福利 前言 机器学习和深度学习是当前最热门的技术领域之一&#xff0c;这些技术正在不断地改变我们的生活和工作方式。ChatGPT 是一款基于大规模预训练模型的自然语言处理工…

matlab GUI界面实现ZieglerNicholas调节PID参数

1、内容简介 略 11-可以交流、咨询、答疑 ZieglerNicholas、PID、GUI 2、内容说明 GUI界面实现ZieglerNicholas调节PID参数 通过ZieglerNicholas调节PID参数&#xff0c;设计了GUI 3、仿真分析 略 4、参考论文 略 链接&#xff1a;https://pan.baidu.com/s/1yQ1yDfk-_…

Prometheus+Ansible+Consul实现服务发现

一、简介 1、Consul简介 Consul 是基于 GO 语言开发的开源工具&#xff0c;主要面向分布式&#xff0c;服务化的系统提供服务注册、服务发现和配置管理的功能。Consul 提供服务注册/发现、健康检查、Key/Value存储、多数据中心和分布式一致性保证等功能。 在没有使用 consul 服…

JavaScript如何实现钟表效果,时分秒针指向当前时间,并显示当前年月日,及2024春节倒计时,源码奉上

本篇有运用jQuery&#xff0c;记得引入jQuery库&#xff0c;否则不会执行的喔~ <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title></title> <meta name"chenc" content"Runoob"> <met…