当前位置: 首页 > news >正文

C++设计模式:观察者模式(三)

1、定义与动机

观察者模式定义:定义对象间的一种1对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生比改变时,所有依赖于它的对象都得到通知并且自动更新

  • 再软件构建过程中,我们需要为某些对象建立一种“通知依赖关系“——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,僵尸软件不能很好地抵御变化。
  • 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。
2、举例分析
  • 例如点击button将一个文件分割成指定数量的功能,在分割过程中一般有一个合理的类似于进度条的通知功能,可以看到当前分割的进度
  • 很容易写出下面的代码:
    • MainForm在收到触发button按钮的操作之后拿到文件名、需求文件个数就调用FileSplitter进行分割
    • FileSplitter类中依赖一个ProgressBar控件,然后在split分割的过程中计算当前分割的进度,将值会写到ProgressBar控件中用于同步展示
  • 但是这样写并不好:
    • 首先可以思考到的一个问题:ProgressBar写死了,我们只能使用这个控件来实现,如果想换个控件、换个方式或者多个控件来展示似乎不太可行,违背了开闭原则
    • 其次很重要的一点:FileSplitter是一个高层模块, ProgressBar是一个低层模块,形成了高层依赖低层模块。而依赖倒置原则讲的是高层和低层模块都应该依赖其抽象,抽象不能依赖实现细节,实现细节应该依赖抽象。ProgressBar实际是一个实现细节(设置value就能展示)
    • 而这样的一个依赖会产生问题:如果换个形式进度条展示,需要更改需求时很难做到,难以抵御变化。
class FileSplitter{
private:string filePath;int fileNumber;ProgressBar* progressBar;
public:FileSplitter(string filepath, int number): filePath(filepath), fileNumber(number){}void split(){// 1. 分批次读取文件大小// 2. 分批次向小文件写入for(int i = 0;i < fileNumber;i++){// 处理...// 展示处理的进度条progressBar->setValue(1.0*(i+1) / fileNumber);}}
};class MainForm: public Form{
private:TextBox* txtFilepath;TextBox* txtFileNumber;
public:void button_event_split(){string filePath = txtFilepath->getText();int number = atoi(txtFilepath->getText().c_str());FileSplitter fileSplitter(filePath, number);fileSplitter.split();}
};
3、观察者模式
  • 通过分析可知,进度条的展示功能不应该出现在文件分割功能里,应该通知依赖它的地方,进行进度条展示
  • 它只需要向外发送通知即可,至于外面进行如何实现这个进度条展示或者其他功能并不需要它关心
  • 观察者模式的核心就是向外进行通知,外面收到通知的对象如何实现就由它们自己决定
  • 因此观察者模式来做这一需求对上面代码进行改造可以变成如下形式!
3.1、基础优化(一)
class IProgress{
public:virtual void doProgress(double value) = 0;virtual ~IProgress(){}
};class FileSplitter{
private:string filePath;int fileNumber;IProgress *iProgress;
public:FileSplitter(string _filepath, int _number, IProgress *_iProgress): filePath(_filepath), fileNumber(_number), iProgress(_iProgress){}void split(){// 1. 分批次读取文件大小// 2. 分批次向小文件写入for(int i = 0;i < fileNumber;i++){// 处理...// 展示处理的进度条iProgress->doProgress(1.0*(i+1) / fileNumber);}}
};class MainForm: public Form, public IProgress{
private:TextBox* txtFilepath;TextBox* txtFileNumber;ProgressBar *progressBar;
public:void button_event_split(){string filePath = txtFilepath->getText();int number = atoi(txtFilepath->getText().c_str());FileSplitter fileSplitter(filePath, number, this);fileSplitter.split();}virtual void doProgress(double value){progressBar->setValue(value);}
};
3.2、多个观察者(二)
  • 当有多个观察者时,可以通过如下的代码来实现
#include <vector>
class IProgress{
public:virtual void doProgress(double value) = 0;virtual ~IProgress(){}
};class FileSplitter{
private:string filePath;int fileNumber;vector<IProgress*> progressList;
public:FileSplitter(string _filepath, int _number, IProgress *_iProgress): filePath(_filepath), fileNumber(_number), iProgress(_iProgress){}void split(){// 1. 分批次读取文件大小// 2. 分批次向小文件写入for(int i = 0;i < fileNumber;i++){// 处理...// 展示处理的进度条notify_observers(1.0*(i+1) / fileNumber);}}void add_IProgress(IProgress* iProgress){progressList.push_back(iProgress);}void remove_IProgress(IProgress* iProgress){progressList.erase(iProgress);}
protected:void notify_observers(double value){for(auto it = progressList.begin();it != progressList.end();it++){(*it)->doProgress(value)}}
};class MainForm: public Form, public IProgress{
private:TextBox* txtFilepath;TextBox* txtFileNumber;ProgressBar *progressBar;
public:void button_event_split(){string filePath = txtFilepath->getText();int number = atoi(txtFilepath->getText().c_str());FileSplitter fileSplitter(filePath, number, this);// 添加额外的观察者fileSplitter.add_IProgress(...);fileSplitter.split();}virtual void doProgress(double value){progressBar->setValue(value);}
};class ConsoleNotifier: public IProgress{virtual void doProgress(double value){//...具体实现...}
};
4、总结
  • 上面的举例代码中Subject对应FileSplitter、而下面的ConcreteSubject就是那个Vector容器以及加和删除的方法。
  • Observer对应上面的进度条类型
  • ConcreteObserver对应MainForm

在这里插入图片描述

  • 使用面向对象的抽象,Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达到松耦合
  • 目标发送通知时,无需指定观察者,通知(可以携带通知信息做为参数)会自动传播
  • 观察者自己决定是否需要订阅通知,目标对象对此一无所知
  • Observer模式是基于事件的UI框架中非常常用的设计模式,也是MVC模式的重要组成部分

相关文章:

C++设计模式:观察者模式(三)

1、定义与动机 观察者模式定义&#xff1a;定义对象间的一种1对多&#xff08;变化&#xff09;的依赖关系&#xff0c;以便当一个对象&#xff08;Subject&#xff09;的状态发生比改变时&#xff0c;所有依赖于它的对象都得到通知并且自动更新 再软件构建过程中&#xff0c…...

CentOS运行Py脚本报错illegal instruction故障处理

测试Python脚本运行环境及依赖 [root@localhost network]# python3 devops_ping_test1.py Illegal instruction ①、illegal instruction报错 由于本人第一次测试时运行是正常的,但是在测试过程中多次修改、覆盖代码运行后提示Illegal instruction(非法指令),所以不能单…...

软件设计师——1.备考提纲

知识点说明比例软件工程基础知识11开发模型、设计原则、测试方法、质量特性、CMM、Pert图、风险管理14.67%面向对象12面向对象基本概念、面向对象分析与设计、UML、设计模式16.00%数据结构与算法10数组、栈、队列、树与二叉树、图、查找与排序、常见算法13.33%程序设计语言6文法…...

[开源] 基于GRU的时间序列预测模型python代码

基于GRU的时间序列预测模型python代码分享给大家&#xff0c;记得点赞哦 #!/usr/bin/env python # coding: utf-8import time time_start time.time() import numpy as np import matplotlib.pyplot as plt import pandas as pd import math from keras.models import Sequent…...

SQL SERVER 备份

目录 1.备份概念 1.1 为何备份? 1.2 SQL Server 备份模式 2.SQL Server 数据库备份 2.1 借助SSMS备份数据库 2.2 借助 T-SQL 备份数据库 2.3 创建加密备份 2.4 备份文件和文件组 权限 步骤 2.5 备份事务日志 3.维护计划 3.1 完整备份 3.2 差异备份...

提示词专场:从调整提示改善与LLMs的沟通,到利用LLMs优化提示效果

编者按&#xff1a;欢迎阅读“科研上新”栏目&#xff01;“科研上新”汇聚了微软亚洲研究院最新的创新成果与科研动态。在这里&#xff0c;你可以快速浏览研究院的亮点资讯&#xff0c;保持对前沿领域的敏锐嗅觉&#xff0c;同时也能找到先进实用的开源工具。 提示词的好坏决…...

测开面经(pytest测试案例,接口断言,多并发断言)

pytest对用户登录接口进行自动化脚本设计 a. 创建一个名为"test_login.py"的测试文件&#xff0c;编写以下测试脚本 import pytest import requests# 测试用例1&#xff1a;验证登录成功的情况 # 第一个测试用例验证登录成功的情况&#xff0c;发送有效的用户名和密…...

Golang 开发实战day09 - package Scope

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 Golang 教程09 - package Sc…...

24考研-东南大学916经验贴

文章目录 一、个人情况二、初试备考经验1.政治 67&#xff0c;客观382.英语 60&#xff0c;客观大概40左右3.数学 136&#xff0c;客观应该满分4.专业课 数据结构计网 114小分不清楚 三、复试备考经验笔试&#xff1a;C面试复试流程 附一下成绩单&#xff1a; 一、个人情况 本…...

【AI面试】YOLO 如何通过 k-means 得到 anchor boxes的?Yolo、SSD 和 faster rcnn 的正负样本定义

如果你的项目中有目标检测相关的内容,那么本篇内容就一定要好好看看。不会的看到了理解下,会的看看是不是和自己理解的一样。 一、YOLO 如何通过 k-means 得到 anchor boxes的? YOLOv2 和 YOLOv3是目标检测领域中非常流行的算法,它们都使用了anchor boxes来提高检测的准确…...

MySQL高级篇(B-Tree、Btree)

目录 1、Btree&#xff08;B-Tree&#xff09; 1.1、B-Trees的特点 二叉树缺点&#xff1a;顺序插入时&#xff0c;会形成一个链表&#xff0c;查询性能大大降低。大数据量情况下&#xff0c;层级较深&#xff0c;检索速度慢。红黑树&#xff1a;大数据量情况下&#xff0c;层…...

Zookeeper脑裂解决方案

Zookeeper脑裂原因&#xff1a; 主要原因是Zookeeper集群和Zookeeper client判断超时并不能做到完全同步&#xff0c;也就是说可能一前一后&#xff0c;如果是集群先于client发现&#xff0c;那就会出现上面的情况。同时&#xff0c;在发现并切换后通知各个客户端也有先后快慢…...

常用日常脚本

日常脚本 1&#xff1a;主机初始化脚本 通用脚本&#xff1a; curl -s http://内网ip:3333/soft/shell/init/init_vm.sh |sh 以下是单一功能脚本 2&#xff1a;定时检测dns&#xff0c;并修改为固定dns curl -s http://内网ip:3333/soft/shell/init/deploy_dns_product.sh | s…...

Longan Pi 3H 开发板体验

Longan Pi 3H 开发板体验 开箱内容 打开包装&#xff0c;你可以看到以下物品 一个Longan Pi 3H盒子Longan Pi 3H开发板 产品基本介绍 Longan Pi 3H 是基于 Longan Module 3H 核心板的 ARM Linux 开发板&#xff0c;以 H618 (Quad core ARM Cortex-A531.5Ghz , 64-bit) 为主控…...

SpringCloud Alibaba Sentinel 创建流控规则

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第十四篇&#xff0c;即介绍 SpringCloud Alibaba Sentinel 创建流控规则。 二、基本介绍 我们在 senti…...

Mysql底层原理五:如何设计、用好索引

1.索引的代价 空间上的代价 时间上的代价 每次对表中的数据进⾏增、删、改操作时&#xff0c;都需要去修改各个B树索引。⽽且我们讲过&#xff0c;B树每层节点都是按照索引列的值从⼩到⼤的顺序排序⽽组成了双 向链表。不论是叶⼦节点中的记录&#xff0c;还是内节点中的记录&a…...

python学习杂记

做为一个接近40岁的人&#xff0c;开始学习python会有什么结果&#xff1f;反正很迷茫&#xff0c;思维方式也开始下降了&#xff0c;希望可以学得好吧 早期做的是前端开发&#xff0c;java也有所接触&#xff0c;但是都学得不精&#xff0c;后来转做项目管理&#xff0c;把技…...

C# Socket发送、接收结构体

Socket发送&#xff1a;Socket的使用 一、Socket发送结构体 结构体如下&#xff1a; [StructLayout(LayoutKind.Sequential, Pack 1)] public struct OutPoint_ST {public int LeftheartX;public int LeftHeartY;public float WidthHeart;public int RightHeartX;public in…...

ics-05-攻防世界

题目 点了半天只有设备维护中心能进去 御剑扫一下 找到一个css 没什么用 再点击云平台设备维护中心url发生了变化 设备维护中心http://61.147.171.105:65103/index.php?pageindex试一下php伪协议 php://filter/readconvert.base64-encode/resourceindex.php base64解一下…...

Web API(三)之事件流事件委托其他事件

Web API(三)之事件流&事件委托&其他事件 事件流捕获和冒泡事件捕获事件冒泡阻止冒泡解绑事件两种注册事件的区别事件委托其他事件页面加载事件元素滚动事件页面滚动事件-获取位置页面滚动事件-滚动到指定的坐标页面尺寸事件元素尺寸与位置元素尺寸与位置-尺寸...

SSL证书的作用是什么?

SSL证书让网站和用户之间安全传输信息&#xff0c;就像给网络对话加了一把密码锁。它主要做四件事&#xff1a; 1. 证明身份&#xff1a; - 像警察局一样&#xff0c;有个叫“证书颁发机构”的家伙负责检查网站是不是真的。网站要向它证明自己是谁&#xff08;比如&#xff0c;…...

皮具5G智能制造工厂数字孪生可视化平台,推进企业数字化转型

皮具5G智能制造工厂数字孪生可视化平台&#xff0c;推进企业数字化转型。随着信息技术的快速发展&#xff0c;数字化转型已成为企业提升竞争力、实现可持续发展的关键路径。皮具行业&#xff0c;作为一个传统的手工制造业&#xff0c;正面临着巨大的市场变革和技术挑战。如何在…...

RH850从0搭建Autosar开发环境【3X】- Davinci Configurator之Port模块配置详解(MCAL配置)

Port模块配置详解 前言一、如何添加Port模块?1.1 导入Port模块二、Port模块详细配置说明2.1 Port模块问题解决2.2 Port模块配置步骤2.2.1 数据手册查找Port对应的Group2.2.2 配置Port为CAN功能2.2.3 选择芯片型号总结前言 我们还差一个Port模块进行配置io的复用功能选择。就是…...

多叉树题目:子树中标签相同的结点数

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;子树中标签相同的结点数 出处&#xff1a;1519. 子树中标签相同的结点数 难度 5 级 题目描述 要求 给你一个树&#xff08;即一个连通的无向无环图…...

帝国CMS模板源码整站安装说明(图文)

安装步骤 第一步&#xff1a;先把得到的文件解压缩&#xff0c;把文件通过FTP传到空间里。&#xff08;请不要把类似www.lengleng.net这个文件夹传到FTP&#xff0c;请传这个大文件夹下面的所有文件夹和文件到空间根目录&#xff0c;请不要上传到2级目录&#xff0c;除非你自己…...

物联网系统未来的发展趋势

一、引言 物联网系统作为新一代的信息技术&#xff0c;正在逐渐改变我们的生活和工作方式。随着物联网技术的不断发展和应用场景的拓展&#xff0c;未来物联网系统的发展趋势将更加明显。本文将从技术、应用、安全等方面探讨物联网系统未来的发展趋势。 二、技术发展趋势 1.…...

基于支持 GPT 的服务的初创公司

Kafkai&#xff1a;多语言长篇内容生成&#xff0c;AI写作的新趋势 介绍 随着生成式预训练 Transformer (GPT) 的出现&#xff0c;技术世界正在见证范式转变。 这种人工智能驱动的创新不仅仅是一种转瞬即逝的趋势&#xff0c;而是一种趋势。 它已成为科技行业的基石&#xff0c…...

基于springboot实现教师人事档案管理系统项目【项目源码+论文说明】

基于springboot实现IT技术交流和分享平台系统演示 摘要 我国科学技术的不断发展&#xff0c;计算机的应用日渐成熟&#xff0c;其强大的功能给人们留下深刻的印象&#xff0c;它已经应用到了人类社会的各个层次的领域&#xff0c;发挥着重要的不可替换的作用。信息管理作为计算…...

上行上传rsync+inotify

引言 使用inotify通知接口&#xff0c;可以用来监控文件系统的各种变化情况&#xff0c;如文件存取、删除、移动、修改等。利用这一机制&#xff0c;可以非常方便地实现文件异动告警、增量备份&#xff0c;并针对目录或文件的变化及时作出响应。 将inotify机制与rsync工具相结合…...

借助ChatGPT写作:打造学术论文中的亮点与互动

ChatGPT无限次数:点击直达 打造学术论文中的亮点与互动 引言 学术论文是学术界交流思想、探讨问题和展示研究成果的重要形式。如何使学术论文在众多作品中脱颖而出&#xff0c;吸引读者的眼球并激发互动&#xff0c;是每位研究者都关注的问题。本文将介绍如何借助ChatGPT这一…...

搞黄色网站做牢/前端seo主要优化哪些

这里将自己学习Go及其区块链的一些笔记、积累分享一下&#xff0c;如果涉及到了文章、文字侵权&#xff0c;请联系我删除或调整。 声明了一个变量&#xff0c;就会在计算机内存中为其分配一个位置&#xff0c;以便存储、修改和访问该变量的值&#xff0c;这个位置就是该变量的地…...

南昌网站设计系统/排名优化是怎么做的

先上代码//这部分的div的 position 是 fixed 解析&#xff1a;1、先设置的 height 为 100%&#xff1b;2、设置 body 的position 为 absolute&#xff0c;因为它里面的 div 有一个为 fixed&#xff0c;这样可以使得 body 的范围可以包括该div&#xff0c;如果设置为 relatve&am…...

wordpress会员管理/什么叫关键词举例

通俗的讲,一个项目需要三四个人完成,此时公司项目策划人的策划书,主程的大体框架,以及程序员所做好的程序,图片均可以上传至服务端,我们也可以从服务端下载你需要的版本,如果出错,可以返回到你需要的原版本,可以清楚的看到都谁上传了,再比如,张三需要完成一个游戏的商城界面,李…...

设计公司给公司做网站用了方正字体/广告联盟接广告

Objective-C中的数据类型 导航:基本数据类型对象类型id类型1.基本数据类型Objective-C中的基本类型与C语言的基本类型一样,主要有:int,long,float,double,char,void,bool等.值得注意的是,在Foundation框架中,系统为某些数据起了别名,如: NSInteger 是 long ,CGFloat是double,以…...

wordpress仿堆糖/搜索引擎优化是做什么

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 据好好先森爆料&#xff1a;一个站长有60多个客户站&#xff0c;说没就没了&#xff0c;损失惨重。60个域名&#xff0c;全部被禁止解析和转移、而且阿里云帐号被冻结&#xff0c;其中一个域名指向…...

做网站建设平台/河南网站优化

原文&#xff1a;https://www.cnblogs.com/lr393993507/p/5867623.html网上的Eclipse注释模板&#xff0c;在这里稍稍整理一些比较常用的。编辑注释模板的方法&#xff1a;Window->Preference->Java->Code Style->Code Template 然后展开Comments节点就是所有需设置…...