观察者模式(大话设计模式)C/C++版本

观察者模式

在这里插入图片描述

扩展:观察者模式——委托

C++

参考:https://www.cnblogs.com/Galesaur-wcy/p/15905936.html

#include <iostream>
#include <list>
#include <memory>
#include <string>
using namespace std;// Observer类 抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口要做更新接口。
// 观察者一般用一个抽象类或者接口实现,更新接口通常包含一个Update()方法 这个方法叫做更新方法。
class Observer
{
public:virtual void Update(int) = 0;virtual ~Observer() = default;virtual void SetName(const string &observerName) final{m_observerName = observerName;}virtual string GetName() const final{return m_observerName;}protected:string m_observerName;
};// Subject类 可翻译为主题或抽象通知者 一般用一个抽象类或者一个接口实现。他把所有对观察者对象的引用保存
// 在一个聚集里,每个主题都可以又任何数量的观察者。抽象主题提供一个接口,可增加或者删除观察者对象
class Subject
{
public:virtual void Attach(shared_ptr<Observer>) = 0;virtual void Detach(shared_ptr<Observer>) = 0;virtual void Notify() = 0;
};// ConcreteObserver 具体观察者 实现抽象观察角色所要求的更新接口,以便使本身的状态与主题的状态相协调.
// 具体观察者角色可以保存一个指向具体主题对象的引用.具体观察者校色通常用一个具体子类实现
class ConcreteObserver : public Observer
{
public:ConcreteObserver(shared_ptr<Subject> pSubject, const string &observerName): m_pSubject(pSubject){m_observerName = observerName;}void Update(int value) override{cout << "   ConcreteObserver " << m_observerName << " gets the update. New State: " << value << endl;}private:shared_ptr<Subject> m_pSubject;
};class ConcreteObserver2 : public Observer
{
public:ConcreteObserver2(shared_ptr<Subject> pSubject, const string &observerName): m_pSubject(pSubject){m_observerName = observerName;}void Update(int value) override{cout << "   ConcreteObserver2 " << m_observerName << " gets the update. New State: " << value << endl;}private:shared_ptr<Subject> m_pSubject;
};// ConcreteSubject类,叫做具体主题或者具体通知者..将有关状态存入具体观察者对象;在具体主题内部状态改变时...给所有登记过的观察者发出通知.
// 具体主题对象通常用一个具体子类实现.
class ConcreteSubject : public Subject
{
public:void Attach(shared_ptr<Observer> pObserver){m_ObserverList.push_back(pObserver);}void Detach(shared_ptr<Observer> pObserver){m_ObserverList.remove_if([=](const shared_ptr<Observer> &observer){ return observer == pObserver; });}void Notify(){for (const auto &observer : m_ObserverList){cout << "   Notifying -> " << observer->GetName() << endl;observer->Update(m_iState);}}void SetState(int state){cout << "State changed to " << state << endl;m_iState = state;}private:list<shared_ptr<Observer>> m_ObserverList;int m_iState;
};int main()
{auto pSubject = make_shared<ConcreteSubject>();auto pObserver = make_shared<ConcreteObserver>(pSubject, "observer1");auto pObserver2 = make_shared<ConcreteObserver2>(pSubject, "observer2");pSubject->Attach(pObserver);pSubject->Attach(pObserver2);pSubject->SetState(2);pSubject->Notify();cout << endl;pSubject->Detach(pObserver);pSubject->SetState(3);pSubject->Notify();cout << endl;return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>typedef struct Subject Subject;
typedef struct Observer
{char *name;void (*update)(struct Subject *, int, void *);
} Observer;typedef struct Subject
{struct Observer **observers;size_t observer_count;int state;
} Subject;void ConcreteObserverUpdate(struct Subject *subject, int value, void *data)
{printf("   ConcreteObserver get the update. New State: %d\n", value);
}void ConcreteObserver2Update(struct Subject *subject, int value, void *data)
{printf("   ConcreteObserver2 get the update. New State: %d\n", value);
}void attach(struct Subject *subject, Observer *observer)
{Observer **newObservers = realloc(subject->observers, sizeof(Observer *) * (subject->observer_count + 1));if (newObservers == NULL){fprintf(stderr, "Memory allocation failed.\n");exit(EXIT_FAILURE);}newObservers[subject->observer_count++] = observer;subject->observers = newObservers;
}void detach(struct Subject *subject, Observer *observer)
{bool removed = false;int i;for (i = 0; i < subject->observer_count; ++i){if (subject->observers[i] == observer){subject->observer_count--;removed = true;int j;for (j = i; j < subject->observer_count; ++j){subject->observers[j] = subject->observers[j + 1];}break;}}if (!removed){fprintf(stderr, "Observer not found.\n");}
}void notify(struct Subject *subject)
{int i;for (i = 0; i < subject->observer_count; ++i){printf("   Notifying -> %s\n", subject->observers[i]->name);subject->observers[i]->update(subject, subject->state, subject->observers[i]);}
}void setState(struct Subject *subject, int state)
{printf("state changed......\n");subject->state = state;
}void safe_free(void *ptr)
{if (ptr)free(ptr);
}int main()
{Subject *pSubject = (Subject *)malloc(sizeof(Subject));pSubject->observers = NULL;pSubject->observer_count = 0;pSubject->state = 0;Observer observer1 = {.name = strdup("observer1"),observer1.update = ConcreteObserverUpdate,};Observer observer2 = {.name = strdup("observer2"),.update = ConcreteObserver2Update,};attach(pSubject, &observer1);attach(pSubject, &observer2);setState(pSubject, 2);notify(pSubject);printf("\n");detach(pSubject, &observer1);setState(pSubject, 3);notify(pSubject);printf("\n");safe_free(observer1.name);safe_free(observer2.name);safe_free(pSubject->observers);safe_free(pSubject);return 0;
}

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

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

相关文章

人工智能导论笔记

有关知识表示和推理的零碎知识点 人工智能导论复习题和概念-CSDN博客 机器学习篇 机器学习分类&#xff08;根据样本数据是否带有标签&#xff09;&#xff1a;监督的机器学习、无监督的机器学习、半监督学习。 监督学习又称为“有教师学习”。在监督学习中&#xff0c;模型…

MySQL 面试突击指南:核心知识点解析2

事务并发可能引发的问题 MySQL 是一个客户端/服务器架构的软件,对于同一个服务器来说,可以有多个客户端与之连接,每个客户端与服务器连接后,可以称为一个会话(Session)。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就…

在 RK3568 上构建 Android 11 模块:深入解析 m、mm、mmm 编译命令

目录 Android 编译系统概述编译命令简介 环境准备使用 m、mm、mmm 编译模块编译整个源码树编译单个模块编译指定目录下的模块 高级应用并行编译清理编译结果编译特定配置 在 Android 开发中&#xff0c;特别是在 RK3568 这样的高性能平台上&#xff0c;有效地编译和管理模块是确…

什么是距离选通型水下三维激光扫描仪?(下)

距离选通激光水下成像的发展 距离选通激光成像技术始于上世纪60年代&#xff0c;受制于高性能脉冲激光器和选通成像器件发展的制约&#xff0c;激光距离选通成像技术在随后的二十年发展缓慢&#xff0c;直到20世纪90年代&#xff0c;随着硬件技术的不断成熟&#xff0c;该技术…

Prompt 提示词工程:翻译提示

近期在对计算机学习时&#xff0c;许多内容需要看原始的英文论文&#xff0c;对于我这种学渣来说特别不友好&#xff0c;&#x1f937;&#x1f3fb;‍♀️无奈只能一边看翻译&#xff0c;一边学习。 之前有搜到过专门的翻译工具&#xff0c;无奈都是按照字数算费用的&#xf…

【FreeRTOS】删除任务 用遥控器控制音乐

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 学习视频&#xff1a;【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS&#xff08;FreeRTOS教程 基于STM32&#xff0c;以实际项目为导向&#xff09;】 【精准空降到 01:22】 https://www.bilibili.com/video/BV1…

模拟原神圣遗物系统-小森设计项目,设计圣遗物词条基类

项目分析 首先需要理解圣遗物的方方面面 比如说圣遗物主词条部分和副词条部分都有那些特点 稍等一会&#xff1a;原神&#xff0c;启动&#xff01; 在此说明了什么&#xff1f; 这是完全体 &#xff1a;主副 词条都有 如果 升级直接暴击率 那么就留点 或者是另外的元素充能 …

关于笔记本电脑连接电源时触摸板失灵、卡顿、乱飘的问题

目录 前言 问题原因 解决方法 前言 我查阅了相关的资料和方法如下&#xff08;很感谢这位楼主大佬提供的问题所在&#xff09;&#xff1a; 问题原因 解决方法 那么解决方法无非就是几种&#xff08;方法仅供参考&#xff0c;不排除一些危险性&#xff09;&#xff1a; 1…

关于戒断短视频的方法第四次尝试(今天执行的过程中,自己内心逻辑体系又垮了一次,先不要着急,慢慢来)

前面三次失败的原因;无法知道自己有没有戒断自己需要戒断的短视频&#xff08;也就是没有正反馈的记录&#xff0c;自己没有成就感。&#xff09;&#xff0c;自己得通过开源的方式帮助自己建立一种可以进行不断地生活的反馈体制和反馈体系。 戒断抖音短视频或任何类似的社交媒…

“论面向对象的建模及应用”必过范文,软考高级,系统架构设计师论文

论文真题 软件系统建模是软件开发中的重要环节,通过构建软件系统模型可以帮助系统开发人员理解系统,抽取业务过程和管理系统的复杂性,也可以方便各类人员之间的交流。软件系统建模是在系统需求分析和系统实现之间架起的一座桥梁,系统开发人员按照软件系统模型开发出符合设…

【人工智能】—XGBoost算法在构建互联网防火墙异常行为识别模型应用案例

摘要&#xff1a; 近年来&#xff0c;各地党委、政府加快推进新型工业化&#xff0c;部署实施制造强市战略&#xff0c;提出工业企业“智改数转”是推动全市工业经济稳增长的重要引擎&#xff0c;更是稳增长、促发展的重要抓手。今天博主就以互联网防火墙异常行为识别为例给大家…

PCM、WAV,立体声,单声道,正弦波等音频素材

1&#xff09;PCM、WAV音频素材&#xff0c;分享给将要学习或者正在学习audio开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 常用的Audio PCM WAV不同采样率&#xff0c;不同采样深度&#…

LeetCode 187-重复的DNA序列

187. 重复的DNA序列 DNA序列 由一系列核苷酸组成&#xff0c;缩写为 ‘A’, ‘C’, ‘G’ 和 ‘T’.。 例如&#xff0c;“ACGAATTCCG” 是一个 DNA序列 。 在研究 DNA 时&#xff0c;识别 DNA 中的重复序列非常有用。 给定一个表示 DNA序列 的字符串 s &#xff0c;返回所有…

信息安全基础知识(完整)

信息安全基础知识 安全策略表达模型是一种对安全需求与安全策略的抽象概念表达&#xff0c;一般分为自主访问控制模型&#xff08;HRU&#xff09;和强制访问控制模型&#xff08;BLP、Biba&#xff09;IDS基本原理是通过分析网络行为&#xff08;访问方式、访问量、与历史访问…

React框架的来龙去脉,react的技术原理及技术难点和要点,小白的进阶之路

React 框架的来龙去脉&#xff1a;技术原理及技术难点和要点 1. React 的起源与发展 React 是由 Facebook 开发的一个用于构建用户界面的 JavaScript 库。它最初由 Jordan Walke 创建&#xff0c;并在 2013 年开源。React 的出现是为了解决在大型应用中管理复杂用户界面的问题…

linux中Java程序调用C程序中方法的实现方式浅析

在Linux中&#xff0c;Java程序可以通过JNI&#xff08;Java Native Interface&#xff09;来调用C程序的方法。 Linux系统环境&#xff0c;Java调用C的主要流程如下&#xff1a; 1、创建Java类文件&#xff0c;如NativeLibrary.java 2、编写Java代码&#xff0c;加载.so共享库…

mysql中的datetime类型在Java中到底对应哪个时间类型?

因为MySQL中用的是datetime类型&#xff08;年月日 时分秒&#xff09; java.sql.Date 在Java中用 java.sql.Date 接收 但是得到的却只有年月日 前端接收到的是时间戳 java.time.LocalDateTime 在Java中使用 java.time.LocalDateTime 接收 得到的是带时区的时间 前端接收到的…

系统或子系统需要划分为多个配置项的原因

按照国军标438C标准以及美军的MIL-STD 498标准&#xff0c;将一个子系统划分为多个配置项&#xff08;CSCI&#xff09;有助于提高系统的管理、开发、测试和维护的效率和质量。 以下是将一个子系统划分为多个配置项的主要原因&#xff1a; 1. 提高可管理性 简化管理&#xff…

Redis——5、持久化RDB和AOF

一、Redis持久化的两种方法&#xff1a; RDB&#xff08;Redis DataBase Backup file&#xff09;Redis数据备份文件 与AOF&#xff08;Append Only File&#xff09;追加文件 二、RDB 1、介绍 RDB 简单来说就是将物理内存中的数据快照写入磁盘中,当Redis实例宕机时&…

chromedriver114以后版本下载地址汇总chromedriver所有版本下载地址汇总国内源下载

谷歌浏览器版本经常会升级&#xff0c;chromedriver 也得下载匹配的版本 chromedriver 114以前版本下载地址https://registry.npmmirror.com/binary.html?pathchromedriver/ 但是自从115版本及其以后网站就找不到了&#xff0c;因此整理了截止2024年6月16日前所有在windows x6…