[C/C++] -- 观察者模式

news/2024/5/20 19:05:01

观察者模式是一种行为型设计模式,用于定义对象间的一种一对多的依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

观察者模式涉及以下几个角色:

  1. 主题(Subject):也称为被观察者或可观察对象,它维护一系列依赖于它的观察者对象,并提供添加、删除和通知观察者的方法。
  2. 观察者(Observer):定义了一个更新接口,以便在主题状态发生改变时接收通知。
  3. 具体主题(Concrete Subject):实现了主题接口,负责维护观察者列表以及状态变化时通知观察者。
  4. 具体观察者(Concrete Observer):实现了观察者接口,在接收到主题通知时进行相应的更新操作。

观察者模式的核心思想是解耦主题和观察者,使得它们可以独立地变化。主题不需要知道观察者的具体类型和数量,只需要维护一个观察者列表,并在状态变化时通知这些观察者即可。这种松耦合的设计使得系统更加灵活和可扩展。

#include <iostream>
#include <string>
#include <memory>
#include <unordered_map>
#include <list>
using namespace std;/*
行为型模式:主要关注的是对象之间的通信。
观察者-监听者模式(发布-订阅模式)设计模式:主要关注的是对象的一对多的关系,也就是多个对象
都依赖一个对象,当该对象的状态发生改变时,其它对象都能够接收到相应的通知。一组数据(对象) -》通过这一组数据-》 曲线图(对象1)/柱状图(对象2)/圆饼图(对象3)
当数据对象改变时,对象1、对象2、对象3应该及时的收到相应的通知!Observer1   Observer2   Observer3Subject(主题) 主题有更改,应该及时通知相应的观察者,去处理相应的事件
*/
class Observer // 观察者抽象类
{
public:// 处理消息的接口virtual void handle(int msgid) = 0;
};// 第一个观察者实例
class Observer1 : public Observer
{
public:void handle(int msgid){switch (msgid){case 1:cout << "Observer1 recv 1 msg!" << endl;break;default:break;}}
};// 第二个观察者实例
class Observer2 : public Observer
{
public:void handle(int msgid){switch (msgid){case 2:cout << "Observer2 recv 2 msg!" << endl;break;default:break;}}
};// 第三个观察者实例
class Observer3 : public Observer
{
public:void handle(int msgid){switch (msgid){case 1:cout << "Observer3 recv 1 msg!" << endl;break;case 2:cout << "Observer3 recv 2 msg!" << endl;break;case 3:cout << "Observer3 recv 3 msg!" << endl;break;default:break;}}
};class Subject // 主题抽象类
{
public:void addObserver(Observer* observer,int msgid){_subMap[msgid].push_back(observer);/*auto it = _subMap.find(msgid);if(it!=_subMap.end()){it->second.push_back(observer);}else{list<Observer*> li;li.push_back(observer);_subMap.insert({msgid,li});}*/}//主题检测发生改变,通知相应的观察者对象处理事件void dispatch(int msg){auto it = _subMap.find(msg);if(it!=_subMap.end()){for(Observer *obs : it->second){obs->handle(msg);}}}private:unordered_map<int,list<Observer*>> _subMap;
};int main()
{Subject sub;Observer *p1 = new Observer1();Observer *p2 = new Observer2();Observer *p3 = new Observer3();sub.addObserver(p1,1);sub.addObserver(p2,2);sub.addObserver(p3,1);sub.addObserver(p3,2);sub.addObserver(p3,3);int msgid = 0;for(;;){cout<<"输入消息id:";cin>>msgid;if(msgid==-1)break;sub.dispatch(msgid);}return 0;
}


http://www.mrgr.cn/p/62642876

相关文章

(七)JSP教程——session对象

浏览器和Web服务器之间的交互通过HTTP协议来完成&#xff0c;HTTP协议是一种无状态的协议&#xff0c;服务器端无法保留浏览器每次与服务器的连接信息&#xff0c;无法判断每次连接的是否为同一客户端。为了让服务器端记住客户端的连接信息&#xff0c;可以使用session对象来记…

基于springboot+jsp+Mysql的商务安全邮箱邮件收发

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

定时将系统时间更新在日志文件中

获取当前系统时间,把时间转换为特定格式”yy年mm月dd日 星期x tt:mm:ss”,并每隔1s写入到本地磁盘中一个叫做log.txt的文本中,如果文本不存在则创建V1.0 2024年5月9日 发布于博客园实现:设计程序,获取当前系统时间,把时间转换为特定格式”yy年mm月dd日 星期x tt:mm:ss”,…

jQuery-1.语法、选择器、节点操作

jQuery jQueryJavaScriptQuery&#xff0c;是一个JavaScript函数库&#xff0c;为编写JavaScript提供了更高效便捷的接口。 jQuery安装 去官网下载jQuery&#xff0c;1.x版本练习就够用 jQuery引用 <script src"lib/jquery-1.11.2.min.js"></script>…

RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决方法二

参考 RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决 前言 rk3568 rockchip 提供的 u-boot&#xff0c;默认的设备树需要读取 单独分区 resouce.img 镜像中的 设备树文件&#xff0c;也就是 Linux 内核的设备树 dtb 文件&#xff0c;gmac 网络才能正常的 ping 通…

Marin说PCB之国产电源芯片方案 ---STC2620Q

随着小米加入的造车大家庭&#xff0c;让这个本来就卷的要死的造车大家庭更加卷了。随之带来的蝴蝶效应就是江湖上各个造成门派都开始了降本方案的浪潮啊&#xff0c;开始打响价格战了。各家的新能源车企也是不得不开始启动了降本方案的计划了&#xff0c;为了应对降价的浪潮。…

3月空气净化器市场数据分析,热门品牌排行榜揭晓!

三月上旬以来&#xff0c;中国空气净化器行业的规模持续扩大&#xff0c;市场规模和消费需求也在不断提升&#xff0c;消费者对高质量空气的需求增加。智能化是当前空气净化器市场的一个重要发展方向&#xff0c;这类产品集成了空气过滤、监测等功能&#xff0c;满足了现代消费…

Linux0.11中MINIX 文件系统

阅读linux 的源码的时候对minix 文件系统有很多的疑惑&#xff0c;根据自己的认识将这些做一个总结。 MINIX 文件系统由六个部分组成&#xff0c;分别是引导块&#xff0c;超级块&#xff0c;i结点位图&#xff0c;逻辑块位图&#xff0c;i结点&#xff0c;数据块。 引导块&am…

【动态规划】:路径问题_地下城游戏

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本专栏是关于各种算法的解析&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结构专栏&…

ChatPPT开启高效办公新时代,AI赋能PPT创作

目录 一、前言二、ChatPPT的几种用法1、通过在线生成2、通过插件生成演讲者模式最终成品遇到问题改进建议 三、ChatPPT其他功能 一、前言 想想以前啊&#xff0c;为了做个PPT&#xff0c;我得去网上找各种模板&#xff0c;有时候还得在某宝上花钱买。结果一做PPT&#xff0c;经…

【driver2】设备读写,同步和互斥,ioctl,进程休眠,时间和延时,延缓

文章目录 1.实现设备读写&#xff1a;write函数中一个进程写没问题&#xff0c;两进程写&#xff1a;第一个进程运行到kzalloc时&#xff0c;第二个进程也执行了kzalloc&#xff0c;只第二个进程地址保存在c中&#xff0c;第一个进程分配内存空间地址丢失造成内存泄漏。第一个进…

Spring-依赖来源

依赖来源 1 Spring BeanDefinition&#xff08;xml,注解&#xff0c;BeanDefinitionBuilder, 还有API实现的单例对象&#xff09; 2 Spring 内建BeanDefinition 3 内建单例对象 依赖注入和依赖查找的区别 Context.refresh() 的时候会调用这个方法&#xff1a;prepareBeanF…

微服务---gateway网关

目录 gateway作用 gateway使用 添加依赖 配置yml文件 自定义过滤器 nacos上的gateway的配置文件 我们现在知道了通过nacos注册服务&#xff0c;通过feign实现服务间接口的调用&#xff0c;那对于不同权限的用户访问同一个接口&#xff0c;我们怎么知道他是否具有访问的权…

FileLink文件摆渡技术解析:如何实现数据的安全摆渡与隔离

文件摆渡系统&#xff0c;这一现代科技名词&#xff0c;蕴含着深刻的科技内涵和广泛的应用前景。简而言之&#xff0c;文件摆渡系统是一种高效、安全的文件传输工具&#xff0c;它能够在不同的网络环境之间实现文件的快速、稳定传输。在今天的数字化时代&#xff0c;随着数据量…

Linux(openEuler、CentOS8)企业内网DHCP服务器搭建(固定Mac获取指定IP)

----本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS8基本一致&#xff0c;可参考本文&#xff09;---- 目录 一、知识点二、实验&#xff08;一&#xff09;为服务器配置网卡和IP&#xff08;二&#xff09;为服务器安装DHCP服务软件&#xff08;三&a…

【JAVA】类加载过程,以及类加载器

类加载过程&#xff0c;以及类加载器 一、类加载的过程二、类加载器介绍三、跨类加载三、举例说明 一、类加载的过程 类加载是Java虚拟机&#xff08;JVM&#xff09;将类文件加载到内存中并转换成对应的类对象的过程。它确保了类文件能够正确加载并转换成可执行的类对象&…

【半个月我拿下了软考证】软件设计师高频考点--系统化教学-网络安全

&#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;软件设计师考点暴击 ⭐&#x1f170;️进入狂砍分⭐ ⭐软件设计师高频考点文档&#xff0c; ⭐软件设计师高频考点专栏 ⭐软件设计师高频考点⭐ &#x1f3b6;&#xff08;A) 考点1&#xff0c;网络攻击 理解记忆 &#…

初学python记录:力扣1652. 拆炸弹

题目&#xff1a; 你有一个炸弹需要拆除&#xff0c;时间紧迫&#xff01;你的情报员会给你一个长度为 n 的 循环 数组 code 以及一个密钥 k 。 为了获得正确的密码&#xff0c;你需要替换掉每一个数字。所有数字会 同时 被替换。 如果 k > 0 &#xff0c;将第 i 个数字用…

【数据库原理及应用】期末复习汇总高校期末真题试卷06

试卷 一、选择题 1&#xff0e; ________是长期存储在计算机内的有组织,可共享的数据集合. A.数据库管理系统 B.数据库系统 C.数据库 D.文件组织 1&#xff0e; 有12个实体类型&#xff0c;并且它们之间存在15个不同的二元联系&#xff0c;其中4个是1:1联系类型&#xff0c;5…

pgsql查看指定模式的存储过程

pgsql查看指定模式的存储过程 在 PostgreSQL 中&#xff0c;如果你想要查看指定模式的存储过程&#xff08;也称为函数&#xff09;&#xff0c;你可以使用 \df 或 \df 命令在 psql 命令行工具中&#xff0c;或者使用 SQL 查询来从 pg_catalog 系统模式中查询。 \df命令行查询…