设计模式——观察者模式(发布/订阅模式)

观察者模式(发布/订阅模式)

是一种行为模式,允许你定义一种订阅机制,可在对象事件发生时通知多个“观察”该对象的其他对象

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使得它们能够自动更新自己。
在这里插入图片描述

#include <iostream>
#include <list>
#include <string>using namespace std;// 观察者(订阅者)的抽象类,里面包含一个Update方法
class IObserver
{
public:virtual ~IObserver(){};virtual void Update(const string &message_from_subject) = 0;
};// 主题/通知者(发布者)的抽象类,里面包含add、remove等方法
class ISubject
{
public:virtual ~ISubject(){};virtual void Attach(IObserver *observer) = 0;virtual void Detach(IObserver *onserver) = 0;virtual void Notify() = 0;
};// 发布者在状态发生变化时通知观察者
class Subject : public ISubject
{
public:virtual ~Subject(){cout << "Goodbye, I was the Subject. " << endl;}void Attach(IObserver *observer) override{list_observer_.push_back(observer);}void Detach(IObserver *observer) override{list_observer_.remove(observer);}void Notify() override{auto iterator = list_observer_.begin();cout << "There are " << list_observer_.size() << " observers in the list. " << endl;while (iterator != list_observer_.end()){(*iterator)->Update(message_);++iterator;}}// 状态改变,通知订阅者void CreateMessage(string message = "Empty"){this->message_ = message;this->Notify();}private:list<IObserver *> list_observer_;string message_;
};// 具体的观察者
class Observer : public IObserver
{
public:Observer(ISubject *subject) : subject_(subject) // 依赖抽象,而非依赖具体的subject对象{this->subject_->Attach(this); // 添加到监听列表cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";this->number_ = Observer::static_number_;}virtual ~Observer(){cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";}void Update(const string &message_from_subject) override{message_from_subject_ = message_from_subject;std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";}void RemoveMeFromTheList(){subject_->Detach(this);cout << "Observer \"" << number_ << "\" removed from the list.\n";}private:string message_from_subject_;ISubject *subject_;static int static_number_;int number_;
};int Observer::static_number_ = 0;// 客户端代码
void ClientCode()
{Subject *subject = new Subject;Observer *observer1 = new Observer(subject);Observer *observer2 = new Observer(subject);Observer *observer3 = new Observer(subject);Observer *observer4;Observer *observer5;subject->CreateMessage("Hello World! :D");observer3->RemoveMeFromTheList();subject->CreateMessage("The weather is hot today! :p");observer4 = new Observer(subject);observer2->RemoveMeFromTheList();observer5 = new Observer(subject);subject->CreateMessage("My new car is great! ;)");observer5->RemoveMeFromTheList();observer4->RemoveMeFromTheList();observer1->RemoveMeFromTheList();delete observer5;delete observer4;delete observer3;delete observer2;delete observer1;delete subject;
}int main()
{ClientCode();return 0;
}

输出:

Hi, I'm the Observer "1".
Hi, I'm the Observer "2".
Hi, I'm the Observer "3".
There are 3 observers in the list. 
Observer "1": a new message is available --> Hello World! :D
Observer "2": a new message is available --> Hello World! :D
Observer "3": a new message is available --> Hello World! :D
Observer "3" removed from the list.
There are 2 observers in the list. 
Observer "1": a new message is available --> The weather is hot today! :p
Observer "2": a new message is available --> The weather is hot today! :p
Hi, I'm the Observer "4".
Observer "2" removed from the list.
Hi, I'm the Observer "5".
There are 3 observers in the list. 
Observer "1": a new message is available --> My new car is great! ;)
Observer "4": a new message is available --> My new car is great! ;)
Observer "5": a new message is available --> My new car is great! ;)
Observer "5" removed from the list.
Observer "4" removed from the list.
Observer "1" removed from the list.
Goodbye, I was the Observer "5".
Goodbye, I was the Observer "4".
Goodbye, I was the Observer "3".
Goodbye, I was the Observer "2".
Goodbye, I was the Observer "1".
Goodbye, I was the Subject. 
  • 观察者模式的特点
    观察者模式所做的工作其实就是在解除耦合,让耦合的双方都依赖于抽象,,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化

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

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

相关文章

[机器学习算法]支持向量机

支持向量机&#xff08;SVM&#xff09;是一种用于分类和回归分析的监督学习模型。SVM通过找到一个超平面来将数据点分开&#xff0c;从而实现分类。 1. 理解基本概念和理论&#xff1a; 超平面&#xff08;Hyperplane&#xff09;&#xff1a;在高维空间中&#xff0c;将数据…

接口提示信息国际化, 调用LibreTranslate 离线翻译, 国际化支持

文章目录 背景实现方式步骤下载并部署离线翻译服务;前端接入 背景 将接口返回内容进行翻译, 以适配多语言需求; 实现方式 前端拦截接口返回内容, 调用离线翻译服务进行翻译, 翻译之后再进行相应的提示 参考资料: 离线翻译服务: https://github.com/LibreTranslate/LibreTra…

Revo Uninstaller Pro:专业卸载工具,为您的电脑系统深度清洁

Revo Uninstaller Pro 是一款功能强大的专业卸载工具&#xff0c;为用户提供了全面而高效的软件卸载解决方案。 在日常使用电脑的过程中&#xff0c;我们经常会遇到软件卸载不干净的问题&#xff0c;残留的文件和注册表项不仅占用宝贵的磁盘空间&#xff0c;还可能影响系统的稳…

36.6K star!Immich - 一款开源高性能的自托管照片和视频备份方案

大家好&#xff0c;今天给大家分享的是一个高性能的自托管照片和视频备份方案。 Immich 是一个图片管理和分享平台&#xff0c;它允许用户高效地组织、存储和访问他们的照片和视频集合。这个项目特别设计来优化个人和家庭的多媒体内容管理体验&#xff0c;提供了诸如自动备份、…

Function:控制继电器上下电,上电后adb登录,copy配置文件

import serial import time import datetime import subprocess import osdef append_to_txt(file_path, content):if os.path.exists(file_path):with open(file_path, a) as file: # 使用 a 模式打开文件进行追加file.write(content \n) # 追加内容&#xff0c;并换行else…

Hbase存储倒排索引

Hbase存储倒排索引 1. 倒排索引简介 定义&#xff1a;倒排索引是搜索引擎用于快速全文搜索的数据结构&#xff0c;它将文档中出现的每个词与包含该词的文档列表相关联。组成&#xff1a;倒排索引由两部分组成&#xff1a;词典和倒排文件。词典包含所有唯一词项&#xff0c;倒…

python编程笔记

python import库失败&#xff1a;原因是解释器选择不对&#xff0c;pip3 install numpy是把numpy库安装在3.xxx的python解释器中&#xff0c;但是我是在3.9.6的解释器下运行的&#xff0c;所以找不到&#xff0c;此时需要把解释器换成3.11.9即可。 Super(Net,self)._init_() 这…

am62x芯片安全类型确认(HS-SE, HS-FS or GP)

文章目录 芯片安全类型设置启动方式获取串口信息下载脚本运行脚本示例sk-am62x板卡参考芯片安全类型 AM62x 芯片有三个安全级别。 • GP:通用版本 • HS-FS:高安全性 - 现场安全型 • HS-SE:高安全性 - 强制安全型 在SD卡启动文件中,可以查看到, 但板上的芯片,到底是那…

Flutter-无限循环滚动标签

1. 序章 在现代移动应用开发中&#xff0c;滑动视图是常见的交互模式之一。特别是当你需要展示大量内容时&#xff0c;使用自动滚动的滑动视图可以显著提升用户体验。在这篇文章中&#xff0c;我们将讨论如何使用 Flutter 实现一个自动滚动的列表视图。 2. 效果 3. 实现思路 …

5.数据结构-树

数据结构中的树是一种抽象数据类型&#xff0c;它是由节点组成的层次结构。树的每个节点可以包含零个或多个子节点&#xff0c;但只能有一个父节点&#xff08;除了根节点&#xff0c;它没有父节点&#xff09;。以下是树的一些基本概念和特性&#xff1a; 基本概念 节点&…

Nvidia Isaac Sim 入门教程 2024(3)图形界面

Isaac Sim 基本使用 版权信息 Copyright 2023-2024 Herman YeAuromix. All rights reserved.This course and all of its associated content, including but not limited to text, images, videos, and any other materials, are protected by copyright law. The author …

深度学习的泛化能力的一些思考

问题&#xff1a; 为什么人类认识了某物体的之后&#xff0c;换场景也认识该物体&#xff0c;但深度学习网络搭建的模型&#xff0c;比如deeplab、yolo等&#xff0c;训练好的模型&#xff0c;换一个不同的场景之后&#xff0c;就识别不出来了&#xff0c;这是为什么&#xff…

项目二 OpenStack快速入门

任务一 熟悉OpenStack图形界面操作 1.1 Horizon项目 •各OpenStack服务的图形界面都是由Horizon提供的。 •Horizon提供基于Web的模块化用户界面。 •Horizon为云管理员提供一个整体的视图。 •Horizon为终端用户提供一个自主服务的门户。 •Horizon由云管理员进行管理…

OCC介绍及框架分析

1.OCC介绍 Open CASCADE &#xff08;简称OCC&#xff09;是一开源的几何造型引擎&#xff0c;OCCT库是由Open CASCADE公司开发和市场运作的。它是为开源社区比较成熟的基于BREP结构的建模引擎&#xff0c;能够满足二维三维实体造型和曲面造型&#xff0c;国内研究和使用它的单…

计算几何【Pick定理】

Pick 定理 Pick 定理&#xff1a;给定顶点均为整点的简单多边形&#xff0c;皮克定理说明了其面积 A {\displaystyle A} A 和内部格点数目 i {\displaystyle i} i、边上格点数目 b {\displaystyle b} b 的关系&#xff1a; A i b 2 − 1 {\displaystyle Ai{\frac {b}{2}}…

操作系统 文件系统

实验目的&#xff1a; 掌握文件系统设计的基本思想。理解掌握文件系统基本数据结构的设计。理解掌握文件操作中涉及的数据结构访问过程。 实验内容&#xff1a; 1、编程实现一个简单的内存文件系统。实现Linux常见的一些文件操作命令。比如&#xff1a;ls/cat/cp/rm等。 实…

Nginx如何实现负载均衡配置

一、引言 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;它以其稳定性、丰富的功能集、低系统资源消耗和简单的配置而广受欢迎。在大型网站和分布式系统中&#xff0c;Nginx常被用作负载均衡器&#xff0c;将请求分发到多个后端服务器上&#xff0c;以提高系统的整体性能…

在实现物体测距,使用射线时自己导致的bug。。

问题 我是想相交的到点以后&#xff0c;直接塞入对应交到的物体里用一个SphereGeometry显示(不测量的时候&#xff0c;寻找其父元素移除)。 进行一番操作以后&#xff0c;发现显示的位置始终不对。 经过一段时间的思考&#xff0c;发现使用intersects[0].object.worldToLocal(…

链表经典面试题--链表修至圆满

目录 1.环形链表 a.为什么一定会相遇&#xff0c;有没有可能会错过&#xff0c;永远追不上&#xff1f;请证明 b.slow一次走1步&#xff0c;fast走3步 4步 5步 n步还一定追得上吗 请证明 2.环形链表2 3.随机链表的复制 1.环形链表 141. 环形链表 - 力扣&#xff08;Lee…

数学建模基础:数学建模概述

目录 前言 一、数学建模的步骤 二、模型的分类 三、模型评价指标 四、常见的数学建模方法 实际案例&#xff1a;线性回归建模 步骤 1&#xff1a;导入数据 步骤 2&#xff1a;数据预处理 步骤 3&#xff1a;建立线性回归模型 步骤 4&#xff1a;模型验证 步骤 5&…