C++设计模式(观察者模式)

一、介绍

1.动机

在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”,即一个对象的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将使软件不能很好地抵御变化。

使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系,从而实现软件体系结构的松耦合。

 

2.定义

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。——GOF

 

3.结构图

731dce10adda49c98474d68fe62136a3.jpeg

 

4.要点总结

使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。

目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。

观察者自己决定是否需要订阅通知,目标对象对此一无所知。

Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的一个重要组成部分。

 

 

二、观察者模式

1.概念

观察者模式的核心在于观察者向被观察者注册,当被观察者状态发生变化时,通知观察者更新。实现时可以使用容器类来管理观察者列表,以便在状态变化时能够遍历并通知所有观察者。

①优点:

  • 实现了松散耦合,观察者和被观察者之间没有直接的依赖关系。
  • 支持广播通信,一个对象的状态变化可以轻松地通知所有观察者对象。

②缺点:

  • 如果观察者对象过多,可能会影响程序的性能。
  • 如果观察者和被观察者之间有循环依赖的话,可能会导致系统崩溃。

 

2.实现要点

 

  • 抽象观察目标:维护一个观察者列表,提供添加、删除和通知观察者的接口。
  • 具体观察目标:实现抽象观察目标提供的接口,当状态改变时,通知所有观察者。
  • 抽象观察者:定义一个抽象观察者类,其中包含一个更新接口。
  • 具体观察者:实现更新接口,以便在收到通知时更新自身状态。

 

3.示例

//观察者(抽象类)
class Observer {
public:virtual void update(const string& news) = 0;virtual ~Observer() {}
};//发布者(抽象观察目标)
class Publisher {
public:virtual void attach(Observer* obs) = 0;virtual void detach(Observer* obs) = 0;virtual void notify(const string& news) = 0;virtual ~Publisher() {}
};//新闻发布者(具体观察目标)
class NewsPublisher :Publisher {
private:list<Observer*> newsList;
public:virtual void attach(Observer* obs) override {newsList.push_back(obs);}virtual void detach(Observer* obs) override {newsList.remove(obs);}virtual void notify(const string& news) override {for (auto obs : newsList) {obs->update(news);}}
};//年轻人(具体观察者)
class YoungPeople :public Observer {
private:string name;int age;
public:YoungPeople(const string& n, int a):name(n), age(a) {}virtual void update(const string& news) override {cout << "Young people " << name << " " << age << " " << news << endl;}
};//中年人(具体观察者)
class MiddleAgedPeople :public Observer {
private:string name;int age;
public:MiddleAgedPeople(const string& n, int a):name(n), age(a) {}virtual void update(const string& news) override {cout << "Mid-aged people " << name << " " << age << " " << news << endl;}
};

测试代码:

NewsPublisher news_publisher;
YoungPeople* p1 = new YoungPeople("Alice", 15);
YoungPeople* p2 = new YoungPeople("Bob", 20);
MiddleAgedPeople* p3 = new MiddleAgedPeople("Charlie", 40);
MiddleAgedPeople* p4 = new MiddleAgedPeople("David", 45);news_publisher.attach(p1);
news_publisher.attach(p2);
news_publisher.attach(p3);
news_publisher.attach(p4);
news_publisher.notify("Initial news");
cout << endl;
news_publisher.detach(p2);
news_publisher.detach(p4);
news_publisher.notify("Subsequent news");delete p1;
delete p2;
delete p3;
delete p4;

输出结果:

Young people Alice 15 Initial news
Young people Bob 20 Initial news
Mid-aged people Charlie 40 Initial news
Mid-aged people David 45 Initial newsYoung people Alice 15 Subsequent news
Mid-aged people Charlie 40 Subsequent news

 

 

 

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

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

相关文章

排序算法2

排序算法1-CSDN博客 排序算法1中提及的是较为基础(暴力实现&#xff0c;复杂度较高)的排序算法&#xff0c;不适合于数据量较大的场景&#xff0c;比如序列长度达到1e5 接下来以蓝桥另一道题目来理解其它的排序算法 蓝桥3226 蓝桥账户中心 样例 5 1 5 9 3 7 4、快速排序 快速排…

go结构体匿名“继承“方法冲突时继承优先顺序

在 Go 语言中&#xff0c;匿名字段&#xff08;也称为嵌入字段&#xff09;可以用来实现继承的效果。当你在一个结构体中匿名嵌入另一个结构体时&#xff0c;嵌入结构体的方法会被提升到外部结构体中。这意味着你可以直接通过外部结构体调用嵌入结构体的方法。 如果多个嵌入结…

Ubuntu Server 22.04.5 从零到一:详尽安装部署指南

文章目录 Ubuntu Server 22.04.5 从零到一&#xff1a;详尽安装部署指南一、部署环境二、安装系统2.1 安装2.1.1 选择安装方式2.1.2 选择语言2.1.3 选择不更新2.1.4 选择键盘标准2.1.5 选择安装版本2.1.6 设置网卡2.1.7 配置代理2.1.8 设置镜像源2.1.9 选择装系统的硬盘2.1.10 …

鸿蒙征文|鸿蒙技术分享:使用到的开发框架和技术概览

目录 每日一句正能量前言正文1. 开发环境搭建关键技术&#xff1a;2. 用户界面开发关键技术&#xff1a;3. 应用逻辑开发关键技术&#xff1a;4. 应用测试关键技术&#xff1a;5. 应用签名和打包关键技术&#xff1a;6. 上架流程关键技术&#xff1a;7. 后续维护和更新关键技术…

C++初阶—C++入门

第一章&#xff1a;C关键字(C98) C 总计 63个关键字&#xff0c;下面只是看一下 C 有多少关键字&#xff0c;不对关键字进行具体的讲解。 第二章&#xff1a;命名空间 #include <stdio.h> #include <stdlib.h>int rand 0;int main() {printf("%d\n", r…

马斯克的 AI 游戏工作室:人工智能与游戏产业的融合新纪元

近日&#xff0c;马斯克在 X 平台&#xff08;前身为 Twitter&#xff09;发文称&#xff0c;“太多游戏工作室被大型企业所拥有&#xff0c;xAI 将启动一个 AI 游戏工作室&#xff0c;让游戏再次变得精彩”。这一言论不仅展示了马斯克对游戏行业现状的不满&#xff0c;也揭示了…

数据库期末复习题库

1. Mysql日志功能有哪些? 记录日常操作和错误信息&#xff0c;以便了解Mysql数据库的运行情况&#xff0c;日常操作&#xff0c;错误信息和进行相关的优化。 2. 数据库有哪些备份方法 完全备份&#xff1a;全部都备份一遍表备份&#xff1a;只提取数据库中的数据&#xff0…

opencv 区域提取三种算法

opencv 区域提取三种算法 1.轮廓查找 findContours()函数&#xff0c;得到轮廓的点集集合 cv::vector<cv::vector<Point>> contours;threshold(roiMat,binImg,m_pPara.m_nMinGray,m_pPara.m_nMaxGray,THRESH_BINARY);//膨胀处理Mat dilaElement getStructuringE…

如何快速上手UPR ---查看资源检测报告

上一章说了如何快速使用资源检测器 那么如何修复我们 的不规范资源呢&#xff1f; 我们都知道一些常规的美术资源优化&#xff0c;但是还是会有一些没有注意到的点 导致我们游戏的性能降低 可以看到我们的Animation 的的不规范 检查动画曲线精度 &#xff0c;其实我觉得他是…

摄影相关常用名词

本文介绍与摄影相关的常用名词。 曝光 Exposure 感光元件接收光线的过程&#xff0c;决定图像的明暗程度和细节表现。 光圈 Aperture 控制镜头进光量的孔径大小&#xff0c;用 F 值&#xff08;f-stop&#xff09; 表示。 光圈越大&#xff08;F 值越小&#xff09;&#xff0c…

NeuIPS 2024 | YOCO的高效解码器-解码器架构

该研究提出了一种新的大模型架构&#xff0c;名为YOCO&#xff08;You Only Cache Once&#xff09;&#xff0c;其目的是解决长序列语言模型推理中的内存瓶颈。YOCO通过解码器-解码器结构的创新设计&#xff0c;显著减少推理时的显存占用并提升了长序列的处理效率。 现有大模…

webrtc视频会议学习(三)

文章目录 关联&#xff1a;源码搭建coturn服务器nginx配置ice配置需服务器要开放的端口 效果 关联&#xff1a; webrtcP2P音视频通话&#xff08;一&#xff09; webrtcP2P音视频通话&#xff08;二&#xff09; webrtc视频会议学习&#xff08;三&#xff09; 源码 WebRTC…

C++ 红黑树 【内含代码】

1. 红黑树 1.1 红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个节点上增加一个存储为表示节点的颜色&#xff0c;可以使Red或Black。通过对任何一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出两倍&…

黑马程序员Java笔记整理(day05)

1.面向对象编程 2.用法 3.对象是什么 4.对象在计算机中是啥 5.无参与有参构造器 小结: 6.this的作用 7.小结 8.封装 9.小结 10.实体类 11.小结 12.static 13.小结 14.static修饰方法 15.static应用前景 16.几个注意事项 17.java中可以直接用类的名字创建数组&#xff0c;如: M…

Flink在Linux系统上的安装与入门

一、Flink的引入 这几年大数据的飞速发展&#xff0c;出现了很多热门的开源社区&#xff0c;其中著名的有Hadoop、Storm&#xff0c;以及后来的Spark&#xff0c;他们都有着各自专注的应用场景。Spark 掀开了内存计算的先河&#xff0c;也以内存为赌注&#xff0c;赢得了内存计…

服务器命令行复制文件

服务器拷贝大文件太慢&#xff0c;而且容易断线&#xff0c;可以采用命令行复制文件 复制windows server服务器文件到linux服务器 scp D:\bim\uploadPath.zip ruoyixx.xx.xx.xx:/home/ruoyi/temp/uploadPath.zip 复制linux服务器文件到windows server服务器 scp ruoyixx.xx.…

(超详细图文详情)Navicat 配置连接 Oracle

1、下载依赖文件 Oracle官网下载直链&#xff1a;https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 夸克网盘下载&#xff08;oracle19c版本&#xff09;&#xff1a;https://pan.quark.cn/s/5061e690debc 官网下载选择对应 Oracle 版…

内网不出网上线cs

一:本地正向代理目标 如下&#xff0c;本地(10.211.55.2)挂好了基于 reGeorg 的 http 正向代理。代理为: Socks5 10.211.55.2 1080python2 reGeorgSocksProxy.py -l 0.0.0.0 -p 1080 -u http://10.211.55.3:8080/shiro/tunnel.jsp 二&#xff1a;虚拟机配置proxifer 我们是…

[2024年3月10日]第15届蓝桥杯青少组stema选拔赛C++中高级(第二子卷、编程题(2))

方法一&#xff08;string&#xff09;&#xff1a; #include <iostream> #include <string> using namespace std;// 检查是否为回文数 bool isPalindrome(int n) {string str to_string(n);int left 0, right str.size() - 1;while (left < right) {if (s…

Spring MVC练习(前后端分离开发实例)

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f439;今日诗词:二十五弦弹夜月&#xff0c;不胜清怨却飞来&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4…