C++设计模式---观察者模式

1、介绍

        观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,它的所有依赖者(观察者)都会自动收到通知并更新。

包含组件如下:

        (1)主题(Subject):主题是一个接口,可以把所有观察者对象登记到其观察者列表中,并且当它的内部状态发生改变时,会自动通知所有登记过的观察者对象。【在类内部建立一个vector记录所有的观察者,当主体发生变化时,遍历通知】。【一个抽象类】。

        (2)具体主题(ConcreteSubject):具体主题实现了主题接口,在内部状态发生改变时,会主动通知所有登记过的观察者对象。【抽象类的子类】。

        (3)观察者(Observer):观察者是一个接口,为所有的具体观察者定义一个更新接口,使得在得到主题的通知时更新自己。【一个抽象类】。

        (4)具体观察者(ConcreteObserver):具体观察者实现了观察者接口,该接口保持一个指向具体主题的引用,以便在主题状态发生改变时得到通知。【抽象类的子类】。

2、示例

#include <iostream>  
#include <list>  
#include <string>  // 观察者接口  
class Observer {
public:virtual ~Observer() {}virtual void update(const std::string& message) = 0;
};// 具体观察者1 
class ConcreteObserver1 : public Observer {
private:std::string name;
public:ConcreteObserver1(const std::string& name) : name(name) {}void update(const std::string& message) override {std::cout << name << " 1111 received: " << message << std::endl;}
};// 具体观察者2 
class ConcreteObserver2 : public Observer {
private:std::string name;
public:ConcreteObserver2(const std::string& name) : name(name) {}void update(const std::string& message) override {std::cout << name << " 2222 received: " << message << std::endl;}
};// 主题接口  
class Subject {
public:virtual ~Subject() {}virtual void attach(Observer* observer) = 0;virtual void detach(Observer* observer) = 0;virtual void notifyObservers() = 0;
};// 具体主题1 
class ConcreteSubject1 : public Subject {
private:std::list<Observer*> observers;std::string state;
public:// 添加观察者void attach(Observer* observer) override {observers.push_back(observer);}// 删除观察者void detach(Observer* observer) override {observers.remove(observer);}// 通知观察者void notifyObservers() override {for (auto observer : observers) {observer->update(state);}}// 设置状态void setState(const std::string& newState) {state = newState;notifyObservers();}
};// 具体主题2
class ConcreteSubject2 : public Subject {
private:std::list<Observer*> observers;std::string state;
public:// 添加观察者void attach(Observer* observer) override {observers.push_back(observer);}// 删除观察者void detach(Observer* observer) override {observers.remove(observer);}// 通知观察者void notifyObservers() override {for (auto observer : observers) {observer->update(state);}}// 设置状态void setState(const std::string& newState) {state = newState;notifyObservers();}
};int main() {ConcreteSubject1 subject1;ConcreteSubject2 subject2;Observer* observer1 = new ConcreteObserver1("Observer 1111");Observer* observer2 = new ConcreteObserver1("Observer 1112");Observer* observer3 = new ConcreteObserver2("Observer 2221");Observer* observer4 = new ConcreteObserver2("Observer 2222");subject1.attach(observer1);subject1.attach(observer2);subject1.attach(observer3);subject1.attach(observer4);subject1.setState("Hello, observers!");// 不再需要观察者时,应该将其从主题中分离并删除  subject1.detach(observer1);subject1.detach(observer4);subject1.setState("Hello, observers 2 and 3!");delete observer1;delete observer2;delete observer3;delete observer4;std::cout << "===============================================" << std::endl;Observer* observer5 = new ConcreteObserver1("Observer 1111");Observer* observer6 = new ConcreteObserver1("Observer 1112");Observer* observer7 = new ConcreteObserver2("Observer 2221");Observer* observer8 = new ConcreteObserver2("Observer 2222");subject2.attach(observer5);subject2.attach(observer6);subject2.attach(observer7);subject2.attach(observer8);subject2.setState("Hello, observers!");// 不再需要观察者时,应该将其从主题中分离并删除  subject2.detach(observer6);subject2.detach(observer7);subject2.setState("Hello, observers 5 and 8!");delete observer5;delete observer6;delete observer7;delete observer8;return 0;
}

结果:

Observer 1111 1111 received: Hello, observers!
Observer 1112 1111 received: Hello, observers!
Observer 2221 2222 received: Hello, observers!
Observer 2222 2222 received: Hello, observers!
Observer 1112 1111 received: Hello, observers 2 and 3!
Observer 2221 2222 received: Hello, observers 2 and 3!
===============================================
Observer 1111 1111 received: Hello, observers!
Observer 1112 1111 received: Hello, observers!
Observer 2221 2222 received: Hello, observers!
Observer 2222 2222 received: Hello, observers!
Observer 1111 1111 received: Hello, observers 5 and 8!
Observer 2222 2222 received: Hello, observers 5 and 8!

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

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

相关文章

【Android面试八股文】一图展示 Android生命周期:从Activity到Fragment,以及完整的Android Fragment生命周期

图片来源于&#xff1a;https://github.com/xxv/android-lifecycle Android生命周期&#xff1a;从Activity到Fragment 图&#xff1a;android-lifecycle-activity-to-fragments.png 完整的Android Fragment生命周期 图&#xff1a;complete_android_fragment_lifecycle.png…

人脸考勤项目实训

第一章 Python-----Anaconda安装 文章目录 第一章 Python-----Anaconda安装前言一、Anaconda是什么&#xff1f;二、Anaconda的前世今生二、Windows安装步骤1.官网下载2.安装步骤安装虚拟环境 总结 前言 工欲善其事必先利其器&#xff0c;项目第一步&#xff0c;安装我们的环境…

如何使用Python pottery库

要使用Python的Pottery库,你需要按照以下步骤进行: 你可以通过pip工具来安装Pottery库。打开终端或命令提示符,输入以下命令: pip install pottery 安装完成后,你就可以开始使用Pottery库了。 在你的Python脚本中,首先需要导入Pottery库。通常,你会从pottery模块中导…

Django ListView 列表视图类

ListView是Django的通用视图之一&#xff0c;它用于显示一个对象列表。这个视图将所有的对象作为一个上下文变量传递给模板。 1&#xff0c;创建应用 python manage.py startapp app3 2&#xff0c;注册应用 Test/Test/settings.py Test/Test/urls.py 3&#xff0c;添加模型 …

【EDA】SSTA中最慢路径与最快路径统计计算

假设(X1,X2)为二元高斯随机向量,均值(μ1,μ2),标准差(σ1,σ2),相关系数ρ 定义:X=max(X1,X2),Y=min(X1,X2) SSTA中计算setup/hold的worst delay时即求X、Y,路径N对应维度为N维。 X的概率密度函数PDF为f(x)=f1(-x)+f2(-x),f1和f2为: 其中小Φ和大Φ…

牛客题目数据结构

做过线段树2模板大概可以写出一部分代码&#xff0c;这题主要关键点是怎么维护平方和 借图了 这样处理完maketag的代码就出来了 void maketag(int id,int l,int r,ll v,int opt){if(opt1){seg[id].val*v;seg[id].pfval*(v*v);seg[id].mul*v;seg[id].add*v;}else{seg[id].pfva…

仓库管理业务在WMS与ERP中如何抉择

当然&#xff0c;以下是WMS&#xff08;仓库管理系统&#xff09;与ERP&#xff08;企业资源计划&#xff09;系统在仓库管理中的主要区别和各自的优势的整理&#xff1a; 一、主要区别&#xff1a; 1. 功能范围&#xff1a; - WMS&#xff1a;专注于仓库内部运作&#xff0c;…

【机器学习】决策树模型(个人笔记)

文章目录 多样性指标基尼杂质指数&#xff08;Gini Impurity Index&#xff09;熵&#xff08;Entropy&#xff09; 决策树的应用 源代码文件请点击此处&#xff01; 多样性指标 基尼杂质指数&#xff08;Gini Impurity Index&#xff09; 若集合中包含 m m m 个元素和 n …

LeetCode1318或运算的最小翻转次数

题目描述 给你三个正整数 a、b 和 c。你可以对 a 和 b 的二进制表示进行位翻转操作&#xff0c;返回能够使按位或运算 a OR b c 成立的最小翻转次数。「位翻转操作」是指将一个数的二进制表示任何单个位上的 1 变成 0 或者 0 变成 1 。 解析 这一题就按位依次比较就行了。取这…

[C++数据结构之看懂就这一篇]图(上)

&#x1f4da;博客主页&#xff1a;Zhui_Yi_&#x1f50d;&#xff1a;上期回顾&#xff1a;JAVA面向对象&#xff08;上&#xff09;❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️&#x1f387;追当今朝…

Android 可拖拽的View,限制在父布局中随意拖拽;拖拽结束后可左右吸边;

实现方法一&#xff1a;自定义View 可随意拖动拖拽的View&#xff0c;限制拖动范围是父布局中&#xff1b; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.ViewGroup; …

Simscape Multibody与RigidBodyTree:机器人建模

RigidBodyTree&#xff1a;主要用于表示机器人刚体结构的动力学模型&#xff0c;重点关注机器人的几何结构、质量和力矩&#xff0c;以及它们如何随时间变化。它通常用于计算机器人的运动和受力情况。Simscape Multibody&#xff1a;作为Simscape的一个子模块&#xff0c;专门用…

情景题之小明的Linux实习之旅:linux实战练习1(下)【基础命令,权限修改,日志查询,进程管理...】

小明的Linux实习之旅&#xff1a;基础指令练习情景练习题下 前景提要小明是怎么做的场景1&#xff1a;初识Linux&#xff0c;创建目录和文件场景2&#xff1a;权限管理&#xff0c;小明的权限困惑场景3&#xff1a;打包与解压&#xff0c;小明的备份操作场景4&#xff1a;使用G…

java基础知识(2)

在jdk8之前的版本会使用stringbuilder&#xff0c;而在jdk8之后的版本&#xff08;包含jkd8&#xff09;则会简化&#xff1b; stringbuilder在创建的时候&#xff0c;默认容量为16&#xff0c;容量是最多放多少位&#xff0c;长度是实际已经存放了多少位&#xff1b;如果超过…

现代操作系统(第四版)课后习题-5.输入/输出

五、输入/输出 1.芯片技术的发展已经使得将整个控制器包括所有总线访问逻辑放在一个便宜的芯片上成为可能。这对于图1-6的模型具有什么影响? 图1-6展示的是一个计算机系统的硬件架构&#xff0c;包括CPU、存储设备、输入/输出设备等的连接关系。芯片技术的发展&#xff0c;尤…

力扣:209. 长度最小的子数组(Java,双指针,滑动窗口)

目录 题目描述&#xff1a;示例 1&#xff1a;示例 2&#xff1a;代码实现&#xff1a; 题目描述&#xff1a; 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的子数组[numsl, numsl1, …, numsr-1, numsr] &#xf…

【思考】Vue2响应丢失、$set

【思考】Vue2响应丢失、$set vue2响应丢失情况复现原因解决总结 vue2响应丢失情况复现 场景&#xff1a;直接通过数组下标去修改数组造成响应丢失 <template><div><p v-for"(item, index) in list" :key"index">{{item}}</p><…

软件安全技术【太原理工大学】

没有划重点&#xff0c;只说了一句课后题和实验中的内容都可能会出。 2022考试题型&#xff1a;选择20个20分&#xff0c;填空10个10分&#xff0c;名词解释4个20分&#xff0c;简答6个30分&#xff0c;分析与论述2个20分&#xff0c;没找到历年题。 如此看来&#xff0c;这门考…

渗透测试模拟实战(二)-BlueCMS平台

渗透测试 渗透测试是维护网络安全的重要组成部分&#xff0c;可以帮助组织识别并修复潜在的安全漏洞&#xff0c;减少被恶意攻击的风险。然而&#xff0c;进行渗透测试时必须遵守法律和道德规范&#xff0c;确保所有活动都在授权范围内进行。 环境部署&#xff1a; study2016、…

【优选算法】优先级队列 {优先级队列解决TopK问题,利用大小堆维护数据流的中位数}

一、经验总结 优先级队列&#xff08;堆&#xff09;&#xff0c;常用于在集合中筛选最值或解决TopK问题。 提示&#xff1a;对于固定序列的TopK问题&#xff0c;最优解决方案是快速选择算法&#xff0c;时间复杂度为O(N)比堆算法O(NlogK)更优&#xff1b;而对于动态维护数据流…