设计模式之观察者模式(优先使用对象组合的原则)的C++实现

devtools/2024/10/18 14:25:17/

观察者模式又称订阅者发布者模式,本篇介绍主要是利用对象组合大于类继承的设计模式原则实现订阅发布模式,这种设计的优点是想订阅数据的类不需要继承订阅者类的抽象类,减少了一层类的继承;当然,具体情况需要可根据需求进行订阅者发布者模式的代码设计。

代码实现如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>using Callback = std::function<void(int)>;
class Subcribe{
public:Subcribe(Callback func):m_callback(std::move(func)){};void RecievData(int val){printf("Recive data val = %d \n",val);m_callback(val);}private:Callback m_callback;
};//单例基类
template<class T>
class SingleIns{
public:static T& GetInstance(){static T a;return a;}
protected:SingleIns()=default;
};class Publisher:public SingleIns<Publisher>{
public:void Attach(Subcribe* obj){if(std::count(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj) > 0){printf("Attach the subscriber already exist\n");return;}m_vecSubscribers.push_back(obj);};void Detach(Subcribe* obj){auto it = std::find(m_vecSubscribers.begin(),m_vecSubscribers.end(),obj);if(it != m_vecSubscribers.end()){m_vecSubscribers.erase(it);}}void UpdateVal(int val){if(m_vecSubscribers.size() == 0){printf("The m_vecSubscribers is empty\n");return;}if(m_val != val){m_val = val;Notify();}else{printf("The updated data is equal\n");}}private:void Notify(){for(auto it = m_vecSubscribers.begin();it !=m_vecSubscribers.end();it++){(*it)->RecievData(m_val);}};std::vector<Subcribe*>m_vecSubscribers;int m_val;};class User1{
public:void GetData(int val){printf("User1 Get data = %d\n",val);};void Init(){Publisher::GetInstance().Attach(&m_subscirbe);}Subcribe& GetSubObj(){return m_subscirbe;};  //对象组合
private:Subcribe m_subscirbe{std::bind(&User1::GetData,this,std::placeholders::_1)};
};class User2{
public:void GetData(int val){printf("User1 Get data *2 = %d\n",val*2);};void Init(){Publisher::GetInstance().Attach(&m_subscirbe);}Subcribe& GetSubObj(){return m_subscirbe;}; //对象组合
private:Subcribe m_subscirbe{std::bind(&User2::GetData,this,std::placeholders::_1)};
};int main()
{User1 obj;obj.Init();Publisher::GetInstance().UpdateVal(1);Publisher::GetInstance().UpdateVal(2);Publisher::GetInstance().UpdateVal(3);Publisher::GetInstance().UpdateVal(3);Publisher::GetInstance().Detach(&obj.GetSubObj());Publisher::GetInstance().UpdateVal(6);printf("\n**************************\n\n");User2 obj2;obj2.Init();Publisher::GetInstance().UpdateVal(5);Publisher::GetInstance().UpdateVal(6);Publisher::GetInstance().Detach(&obj2.GetSubObj());Publisher::GetInstance().UpdateVal(7);return 0;
}

程序运行结果如下:

7377db541f0d401594075079cd515498.png

附加知识:单例模式C++实现和观察者模式C++实现_实现观察者模式,并画出其类图 c++-CSDN博客


http://www.ppmy.cn/devtools/14579.html

相关文章

MINIO安装的方法(WindowsLiunx)

2 minio安装教程 注&#xff1a;官方中文文档&#xff1a;MinIO对象存储 Windows — MinIO中文文档 | MinIO Windows中文文档 Liunx 安装方&#xff1a;MinIO对象存储 Linux — MinIO中文文档 | MinIO Linux中文文档 2.1 下载地址 https://dl.min.io/server/minio/…

web前端学习笔记2

2. 网页穿上美丽外衣 2.1 什么是CSS CSS (Cascading Style Sheets,层叠样式表),是一种用来为结构化文档(如 HTML 文档或 XML 应用)添加样式(字体、间距和颜色等)的计算机语言,CSS 文件扩展名为 .css。 CSS样式包括对字体、颜色、边距、高度、宽度、背景图片、网页定位…

Android判断应用是否在前台运行

Android判断应用是否在前台运行 /*** Android判断应用是否在前台运行* 0&#xff1a;异常&#xff1b;1&#xff1a;前台&#xff1b;2&#xff1a;后台&#xff1b;3&#xff1a;未运行&#xff1b;*/private int isFrontShow(Context context) {if (context null) {ret…

SpringBoot Bean管理(扫描、注册、注册条件)

Bean扫描 一般的扫描包路径 需要使用xml标签或者是ComponentScan(basePackages “xxx.xxx”) ,但是在SpringBoot中不需要。 在springBoot 项目的启动类中有一个注解&#xff1a;SpringBootApplication,这个注解包含以下注解&#xff1a; 但是ComponentScan并没有指明包路径…

Azure AKS集群监控告警表达式配置

背景需求 Azure AKS集群中&#xff0c;需要对部署的服务进行监控和告警&#xff0c;需要创建并启用预警规则&#xff0c;而这里怎么去监控每个pod级别的CPU和内存&#xff0c;需要自己写搜索查询 解决方法 搜索和查询的语句如下&#xff0c;需要自己替换其中的部分信息,其中…

【Java】全套云HIS源码包含EMR、LIS(多医院、卫生机构使用)

云HIS系统简介 SaaS模式Java版云HIS系统源码&#xff0c;在公立二甲医院应用三年&#xff0c;经过多年持续优化和打磨&#xff0c;系统运行稳定、功能齐全&#xff0c;界面布局合理、操作简便。 1、融合B/S版电子病历系统&#xff0c;支持电子病历四级&#xff0c;HIS与电子病…

STM32 串口打印乱码(Cubemx)

STM32 串口打印乱码&#xff08;Cubemx&#xff09; 时钟配置错误&#xff0c;CubeMX默认的外部晶振是25MHz&#xff0c;而板载的晶振为8MHzSTM32F407修改程序将外部25M晶振修改为8M&#xff08;标准库、HAL库&#xff09; 核心问题 芯片型号与晶振配置&#xff1a;使用的ST…

用C#写一个读取pdf文档内容的库

安装这两个库&#xff0c;第二个库一定要安装否则有些pdf文件读取会出现异常 读取 using iText.Kernel.Pdf; using iText.Kernel.Pdf.Canvas.Parser; using iText.Kernel.Pdf.Canvas.Parser.Listener;namespace TestReadPdf {public static class PdfHelper{public static IE…