【设计模式】观察者模式及函数式编程的替代C++

本文介绍观察者模式以及使用函数式编程替代简单的策略模式。

观察者模式

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

当对象间存在一对多关系时,则使用观察者模式(Observer
Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

简单来说,观察者模式需要多个对象观察同一个对象,被观察的对象称为Subject(主题),Subject需要完成观察者的注册(attach),注销(detach)和通知(notify)三个操作。
观察者模式,图片来自菜鸟教程
首先实现一个公共的Observer父类,这个父类只有一个纯虚函数,用来更新自身状态:

struct Observer
{
public:virtual void update() = 0;
};

两个具体的类,实现 update 函数:

struct ConcreteObserver : Observer
{
public:void update() override{std::cout << "State updated!" << std::endl;}
};struct ConcreteObserver2 : Observer
{
public:void update() override{std::cout << "State updated! 2" << std::endl;}
};

接下来实现被观察者公共类,包含添加、删除、通知所有观察者三个接口:

struct Subject
{
public:virtual void attach(Observer *observer) = 0;virtual void detach(Observer *observer) = 0;virtual void notify() = 0;
};

具体的被观察者类,实现这三个接口:

struct ConcreteSubject : Subject
{
public:void attach(Observer *observer) override{observers.push_back(observer);}void detach(Observer *observer) override{for (auto it = observers.begin(); it != observers.end(); it++){if (*it == observer){observers.erase(it);break;}}}void notify() override{for (auto &observer : observers){observer->update();}}private:std::vector<Observer *> observers;
};

测试代码如下:

int main()
{ConcreteSubject subject;ConcreteObserver observer1;ConcreteObserver2 observer2;subject.attach(&observer1);subject.attach(&observer2);subject.notify();subject.detach(&observer1);subject.notify();
}

结果

函数式编程下的观察者模式

首先需要介绍下C语言的函数指针。所谓函数指针即定义一个指向函数的指针变量,格式如下:

typedef void (*Callback)();

这样就定义了一个变量名为Callback的指针变量,指向一个参数为void,返回值也为void的函数。我们用这种指针变量,就能将整个观察者类改成函数。

两个观察者函数:

void callback1()
{std::cout << "State updated!" << std::endl;
}void callback2()
{std::cout << "State updated! 2" << std::endl;
}

被观察的类。原先调用观察者类的地方全部改为函数调用:

struct ConcreteSubject
{
public:void attach(Callback callback){observers.push_back(callback);}void detach(Callback callback){for (auto it = observers.begin(); it != observers.end(); it++){if (*it == callback){observers.erase(it);break;}}}void notify(){for (auto &observer : observers){observer();}}private:std::vector<Callback> observers;
};

观察者模式与回调

我给函数指针起名为Callback。事实上,当只有一个观察者的时候,观察者模式的机制就等同于回调模式。因此可以认为,回调模式是一种特殊的观察者模式。

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

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

相关文章

Spring中Bean的作用域、实例化方式、生命周期、循环依赖问题

Spring中Bean的作用域、实例化方式、生命周期、循环依赖问题 一、Bean的作用域1.singleton2.prototype3.其他scope值 二、Bean的实例化方式1.通过构造方法实例化2.通过简单工厂模式实例化3.通过factory-bean实例化4.通过FactoryBean接口实例化5.BeanFactory和FactoryBean的区别…

【大厂AI课学习笔记NO.60】(13)模型泛化性的评价

我们学习了过拟合和欠拟合&#xff0c;具体见我的文章&#xff1a;https://giszz.blog.csdn.net/article/details/136440338 那么今天&#xff0c;我们来学习模型泛化性的评价。 泛化性的问题&#xff0c;我们也讨论过了&#xff0c;那么如何评价模型的泛化性呢&#xff1f; …

激光SLAM技术助力富唯智能复合机器人的应用场景无限拓展

随着科技的不断进步&#xff0c;智能机器人已成为现代工业、服务、医疗等多个领域的重要角色。而在这一变革中&#xff0c;激光SLAM技术发挥着至关重要的作用。特别是对于富唯智能复合机器人来说&#xff0c;激光SLAM技术不仅提升了其智能化水平&#xff0c;更使其应用场景变得…

【促销定价】背后的算法技术3-数据挖掘分析

【促销定价】背后的算法技术3-数据挖掘分析 01 整体分析1&#xff09;整体概览2&#xff09;类别型特征概览3&#xff09;数值型特征概览 02 聚合分析1&#xff09;天维度2&#xff09;品维度3&#xff09;价格维度4&#xff09;数量维度 03 相关分析1&#xff09;1级品类2&…

无公网ip环境使用DS file软件远程访问内网群晖NAS中储存的文件

文章目录 1. 群晖安装Cpolar2. 创建TCP公网地址3. 远程访问群晖文件4. 固定TCP公网地址5. 固定TCP地址连接 DS file 是一个由群晖公司开发的文件管理应用程序&#xff0c;主要用于浏览、访问和管理存储在群晖NAS&#xff08;网络附加存储&#xff09;中的文件。这个应用程序具有…

echarts如何实现3D饼图(环形图)?

一、实现的效果 二、具体步骤 1.安装依赖 npm install echarts 2.引入echarts import * as echarts from echarts; 注意&#xff1a;这里需要用到echarts-gl&#xff0c;必须单独引入才可以 import echarts-gl; 3.echarts部分代码 我知道这部分内容很多&#xff0c;但只要cv…

羊大师揭秘羊奶与健康,美味的保健佳品

羊大师揭秘羊奶与健康&#xff0c;美味的保健佳品 羊奶确实是一种美味且健康的保健佳品&#xff0c;其独特的营养成分和风味使其成为许多人的健康选择。以下是一些羊奶与健康的关系&#xff1a; 营养丰富&#xff1a;羊奶含有丰富的蛋白质、脂肪、矿物质和维生素&#xff0c;…

ruoyi-nbcio-plus的Vue3前端升级组件后出现的问题(一)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a; http://122.227.135.243:9666 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbach…

大模型ChatGLM-6B实现本地部署

大模型ChatGLM-6B实现本地部署 一、写在前面&#xff1a;二、ChatGLM-6B下载&#xff1a;三、项目所需要的环境配置&#xff1a;四、项目运行&#xff1a;五、遇到的主要问题及解决 一、写在前面&#xff1a; 1、 确保你的电脑中已安装git&#xff0c;git lfs。 2、确保你的电…

浅析前端的堆栈原理以及深浅拷贝原理

浅析前端的堆栈原理以及深浅拷贝原理 首先来看一个案例 const obj {name:hzw,age:18 } let objName2 obj objName2.age 12 console.log(obj,objName2) // {name: hzw, age: 12} {name: hzw, age: 12}这里是不是很奇怪&#xff0c;为什么&#xff0c;为什么我改变objName2的…

AirPods Pro 2 耳机推送新固件,苹果Find My功能助力产品成长

苹果公司面向 AirPods Pro 2&#xff08;包括 USB-C 和 Lightning 版本&#xff09;&#xff0c;推出了全新的测试版固件更新&#xff0c;版本号为 6E188&#xff0c;高于 12 月份发布的 6B34 固件。 苹果和往常一样&#xff0c;并没有提供详细的更新日志或者说明&#xff0c…

算法刷题day20:二分

目录 引言概念一、借教室二、分巧克力三、管道四、技能升级五、冶炼金属六、数的范围七、最佳牛围栏 引言 这几天一直在做二分的题&#xff0c;都是上了难度的题目&#xff0c;本来以为自己的二分水平已经非常熟悉了&#xff0c;没想到还是糊涂了一两天才重新想清楚&#xff0…

力扣区间题:合并区间、插入区间

我们可以将区间按照左端点升序排列&#xff0c;然后遍历区间进行合并操作。 我们先将第一个区间加入答案&#xff0c;然后依次考虑之后的每个区间&#xff1a; 如果答案数组中最后一个区间的右端点小于当前考虑区间的左端点&#xff0c;说明两个区间不会重合&#xff0c;因此…

Java基于springboot的课程作业管理系统

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;课程作业管理系统当然也不能排除在外。课程作业管理系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法…

Linux常见命令总结

1.创建文件夹 mkdir 目录名 mkdir 文件夹名 创建单个文件夹 mkdir 文件夹1 文件夹2 文件夹3 创建多个文件夹 mkdir -p parent/child 创建多级文件夹 2.创建文件 touch 文件名 touch的主要功能有两个,如果要创建的文件的名称存在,将文件的创建时间修改到当前的系统时间(也…

五种常用的可视化项目管理工具

传统的项目管理通常依赖于文本文档&#xff0c;容易造成误解和混乱。在快节奏的商业环境中&#xff0c;没有哪个项目经理愿意处理繁重的文档流程。 另一方面&#xff0c;可视化项目管理通常使用图表和视觉板来展示复杂的项目信息。因此&#xff0c;项目经理能快速了解关键信息…

基于 rk3566 的 uboot 分析 - dts 加载和 dm 模型的本质

文章目录 一、设备树加载使用1、概述2、第一阶段1) fdtdec_setup2) 总结 3、第二阶段1) kernle dtb 编译打包2) 加载流程2.1) board_init2.2) init_kernel_dtb2.3) rockchip_read_dtb_file2.4) rockchip_read_resource_dtb 3) 总结 二、dm 模型1、树的创建1) device_bind_commo…

使用Matlab计算IGRAv2探空站的Tm和PWV

1. 探空站IGRAv2数据 探空站的Tm常作为真值&#xff0c;去检验Tm线性公式或者ERA5 Tm等的精度 。 探空站PWV常作为真值&#xff0c;去检验GNSS PWV等的精度 2. Tm 的计算方法 Tm 的计算方法有两种在前面的文章有讲&#xff0c;这里用 使用水汽压和温度计算Tm。 ei和 Ti 表示…

本地如何配置支付宝模拟支付场景并结合内网穿透实现公网环境调试开发?

文章目录 前言1. 下载当面付demo2. 修改配置文件3. 打包成web服务4. 局域网测试5. 内网穿透6. 测试公网访问7. 配置二级子域名8. 测试使用固定二级子域名访问 前言 在沙箱环境调试支付SDK的时候&#xff0c;往往沙箱环境部署在本地&#xff0c;局限性大&#xff0c;在沙箱环境…

还在犹豫学不学?鸿蒙技术是否有前途的最强信号来了

2024年3月3日 上午10 点&#xff0c;深圳官方账号发布了一篇关于鸿蒙技术发展的重要文章&#xff0c;看到这篇文章后我非常激动&#xff0c;忍不住和大家分享一下&#xff01; 华为鸿蒙系统自提出以来&#xff0c;网友们的态度各不相同&#xff0c;有嘲笑“安卓套壳”的&#…