C++|观察者模式

news2024/11/16 3:45:56

观察者模式:

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

动机:

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

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

总结:

  • 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达致松耦合。
  • 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。
  • 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
  • Observer模式是基于事件的UI框架中非常常用的设计模式,也是 MVC模式的一个重要组成部分。

实践案例

假如现有有一个业务场景,我们需要写一个视频检测器,该检测器会使用图像分割模型对输入的视频流进行检测,如果监测到画面有人,那么需要做针对人的具体操作(比如将人框出来,比如将人截取出来),如果检测到画面中有汽车,也会做具体操作(比如将汽车涂为红色)等等。
这样一个业务场景普通的写法,我们很容易想到,读取视频流,然后对每一帧图像检测,然后写if else
if 检测到人 {…}
else if 检测到汽车 {…}
else if 检测到天空 {…}
这样的实现方式可以满足需求,但是并不满足我们的设计原则
这是一个紧耦合的做法,你的检测器要依赖于其他的视频操作类,不符合我们的依赖倒置原则
我们可以将操作类抽象成一个接口,然后再需要操作的时候,调用接口。这样就解决了这个问题
不过还有一点,在这个业务场景中,操作类有不同的操作,也就是说需要多个操作
因为我们进一步抽象
我们写一个操作基类,然后再写多个操作类1,操作类2,都继承基类
到这一步,其实观察者模型就出来了

观察者模型:
我们可以把视频看作一个被观察者,检测到的结果(人、汽车、树木等),这些相当于信息通知,给谁通知呢?给那些具体的操作类通知,所以我们可以把对人操作的类、对汽车操作的类这些看作观察者。
被观察者将消息发送给观察者,观察者根据消息来做不同的操作(多态)
并且在这个过程中,支持观察者自主选择是否订阅消息。
在这里插入图片描述

代码实现以及注释:

#include <string>
#include <iostream>
#include <list>
using namespace std;


class Observer {// 抽象类(接口)
public:
	virtual void handleVideo(string detectInfo) = 0;
	virtual ~Observer() {}
};

class Observer1 : public Observer {
public:
	virtual void handleVideo(string detectInfo) {
		cout << "截取人" << endl;
	}
};

class Observer2 : public Observer {
public:
	virtual void handleVideo(string detectInfo) {
		cout << "截取汽车" << endl;
	}
};

class VideoDetecter {
	string m_filePath;
	string m_fileName;
	list<Observer*>  m_observerList; // 抽象通知机制,支持多个观察者

public:
	VideoDetecter(string filePath, string fileName) {
		m_filePath = filePath;
		m_fileName = fileName;
	}
	void detect() {
		//1.读取视频流
		cout << "读取视频流:" << m_filePath + m_fileName << endl;
		//2.循环每一帧处理
		int frameNum = 10;
		for (int i = 0; i < frameNum; i++) {
			//假设对第i帧图像处理得到识别结果 结果记作 detectInfo
			string detectInfo = "识别结果";
			sendNotify(detectInfo);//发送通知
		}
	}
	void addObserver(Observer* observer) { //添加观察者
		m_observerList.push_back(observer);
	}
	void removeObserver(Observer* observer) { //移除观察者
		m_observerList.remove(observer);
	}
protected:
	virtual void sendNotify(string detectInfo) {
		list<Observer*>::iterator itor = m_observerList.begin();
		while (itor != m_observerList.end()) {
			(*itor)->handleVideo(detectInfo); //不同观察者对通知做出响应
			itor++;
		}
	}
};

int main() {
	string filePath = "/root/home/videoPath/";
	string fileName = "001.mp4";
	Observer* observer;

	VideoDetecter detecter(filePath, fileName);
	Observer1 ob1;
	Observer2 ob2;
	detecter.addObserver(&ob1);
	detecter.addObserver(&ob2);
	detecter.detect();
	detecter.removeObserver(&ob1);
	detecter.removeObserver(&ob2);
	//detecter.detect();

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习 | 核心概念】那些深度学习路上必经的核心概念,确定不来看看?(一)

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

基于吉萨金字塔建造算法优化的BP神经网络(预测应用) - 附代码

基于吉萨金字塔建造算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于吉萨金字塔建造算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.吉萨金字塔建造优化BP神经网络2.1 BP神经网络参数设置2.2 吉萨金字塔建造算法应用…

SpringBoot与前端交互遇到的一些问题

一、XXX.jar中没有主清单属性 场景&#xff1a; SpringBoot打的jar包在Linux运行报错 解决方案&#xff1a; 百度找了很多都是一样的答案&#xff0c;但是解决不了我的问题&#xff0c;于是我新建了一个springboot项目发现打的jar包可以在Linux上运行。检查了下只要把下面这2个…

R语言之缺失值处理

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/dive-into-AI 】或者公众号【AIShareLab】回复 R语言 也可获取。 文章目录 缺失值处理1. 识别缺失值2. 探索数据框里的缺失值3. 填充缺失值3.1 删除缺失值&#xff1a;na.omit( )、complete.cases( …

机器学习:异常检测实战

文章目录 Anomaly Detection目录任务介绍数据集方法评估Baseline报告报告评价标准 Anomaly Detection 目录 任务介绍 无监督的异常检测 数据集 方法 autoencode 是否能够还原出原始类型图片&#xff0c;基于重构loss来判断是否正常 重构误差当作异常分数 评估 采用ROC和AUC…

Kubernetes入门 十、HPA 自动扩/缩容

目录 概述安装metrics-server使用HPA 概述 我们已经可以通过手动执行 kubectl scale 命令实现Pod的扩缩容&#xff0c;但是这显然不符合 Kubernetes 的定位目标–自动化和智能化。Kubernetes 期望可以通过监测Pod的使用情况&#xff0c;实现 Pod 数量的自动调整&#xff0c;于…

Orange Pi 3B 开发板 开箱评测 和 系统安装教程

香橙派 Orange Pi 3B&#xff08;RK3566&#xff09;开发板 开箱测评 和 系统烧录教程 简介 香橙派 Orange Pi 3B 是一款树莓派大小的单板计算机&#xff0c;但接口更加齐全&#xff0c;包括一个全尺寸 HDMI 接口和一个 M.2 存储插槽&#xff0c;售价199起。 Orange Pi 3B 采…

【Tkinter系列02/5】界面初步和布局

本文是系列文章第二部分。前文见&#xff1a;【Tkinter系列01/5】界面初步和布局_无水先生的博客-CSDN博客 说明 一般来说&#xff0c;界面开发中&#xff0c;如果不是大型的软件&#xff0c;就不必用QT之类的实现&#xff0c;用Tkinter已经足够&#xff0c;然而即便是Tkinter规…

软考:中级软件设计师:OSI/RM七层模型,网络技术标准与协议

软考&#xff1a;中级软件设计师:OSI/RM七层模型 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的…

No117.精选前端面试题,享受每天的挑战和学习

文章目录 断点续传怎么做的秒传怎么实现var let const 块级作用域ts Partial Omit 怎么实现的箭头函数有哪些限制箭头函数为什么不能作为构造函数promise常用apiMap和Object的区别vue怎么实现双向绑定 断点续传怎么做的 断点续传是指在文件下载或上传过程中&#xff0c;当连接…

ForexClub七夕交易大赛启动! 点燃交易之火为爱而战!

在这个充满激情的七夕季&#xff0c;ForexClub与您携手&#xff0c;掀起交易狂潮!点燃您心中的交易热忱&#xff0c;冲锋市场&#xff0c;赢取惊人奖金!别等了&#xff0c;参赛即有机会获得77美元的交易赠金&#xff0c;让我们一同为迸发的交易机会&#xff0c;燃烧一片天! 【大…

直流无刷电机工作原理及有感方波控制

BLDC方波控制 BLDC工作原理BLDC换向驱动过程有感控制模式 BLDC工作原理 首先要知道&#xff0c;BLDC转起来是基于什么原理 BLDC包括定子&#xff08;线圈&#xff09;和转子&#xff08;永磁体&#xff09;&#xff0c;线圈要通电&#xff0c;通电的线圈具有磁场&#xff0c;该…

基于寄生捕食算法优化的BP神经网络(预测应用) - 附代码

基于寄生捕食算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码 文章目录 基于寄生捕食算法优化的BP神经网络&#xff08;预测应用&#xff09; - 附代码1.数据介绍2.寄生捕食优化BP神经网络2.1 BP神经网络参数设置2.2 寄生捕食算法应用 4.测试结果&#xff1a;5…

01.基于自定义MVC架构的用户登录与首页展示实现 — OA项目实践

目录 本章节目标&#xff1a;完成OA项目用户登录及首页展示 一.用户登录 User.java UserDao.java IUserDao.java UserAction.java login.jsp&#xff08;登录界面&#xff09; userManage.jsp (数据绑定&#xff0c;修改&#xff0c;删除) userEdit.jsp&#xff08;用…

windows wvp-gb28181-pro一键安装的脚本流程

流程图 【金山文档】 windows wvp安装脚本流程https://kdocs.cn/l/cataPonNMXNm

信息系统项目管理师(第四版)教材精读思维导图-第四章信息系统管理

请参阅我的另一篇文章&#xff0c;综合介绍软考高项&#xff1a; 信息系统项目管理师&#xff08;软考高项&#xff09;备考总结_计算机技术与软件专业技术_铭记北宸的博客-CSDN博客 本章思维导图PDF格式 本章思维导图XMind源文件 目录 4.1 管理方法 4.2 管理要点 4.1 管理方…

linux并发服务器 —— Makefile与GDB调试(二)

Makefile Makefile&#xff1a;定义规则指定文件的编译顺序&#xff1b;类似shell脚本&#xff0c;执行操作系统命令 优点&#xff1a;自动化编译——通过make&#xff08;解释Makefile文件中指令的命令&#xff09;命令完全编译整个工程&#xff0c;提高软件开发效率&#x…

144. 二叉树的前序遍历-C++

题目来源&#xff1a;力扣 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,2,3]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 代码实现&#xff1a; class Solution { public:vector<int> preorderTraversal(TreeNo…

【Redis】Redis是什么、能干什么、主要功能和工作原理的详细讲解

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Python、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&…

人员着装识别算法 yolo

人员着装识别系统通过yolo网络模型识别算法&#xff0c;人员着装识别系统算法通过现场安装的摄像头识别工厂人员及工地人员是否按要求穿戴着装&#xff0c;实时监测人员的着装情况&#xff0c;并进行相关预警。目标检测架构分为两种&#xff0c;一种是two-stage&#xff0c;一种…