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

c#设计模式-行为型模式 之 观察者模式

定义:

又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者 对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自 动更新自己。

在观察者模式中有如下角色:

  1. Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每 个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
  2. ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具 体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  3. Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知 时更新自己。
  4. ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知 时更新自身的状态。

案例

这里案例使用一个委托进行多播来进行对热水器的观察

加热器类

首先定义一个全局变量,温度temperature,然后使用event声明一个事件,委托名称使用无返回值的Action,参数为int。然后写一个for循环模拟烧水,温度temperature大于95时,执行事件。

public class HeaterSubject
{private int _temperature;public event Action<int> OnBoilEvent;public void BoilWater(){for (int i = 0; i < 100; i++){_temperature++;if (_temperature >= 95){OnBoilEvent.Invoke(_temperature);//触发事件:发出警报,显示水温}}}
}

监视者

热水器上一般都有显示屏和警报器,这里模拟两个观察者,分别是显示器和警报器

因为上面声明的委托参数是int,这里的观察者参数也要匹配,等一下才可以通过多播的形式插入

public class DisPlayObserver
{/// <summary>/// 显示水温/// </summary>/// <param name="temperature"></param>public void Display(int temperature){Console.WriteLine($"显示屏-当前温度是:{temperature}");}
}
public class AlertObserver
{/// <summary>/// 发出警报/// </summary>/// <param name="temperature"></param>public void MakeAlert(int temperature){Console.WriteLine($"语音报警器-温度是{temperature}");}
}

main方法

在main方法中,实现new一个热水器的实例,然后使用多播将多个方法绑定到一个委托实例。当调用此类委托时,所有绑定的方法会被一次全部调用,最后调用热水器的烧水方法

    public static void Main(string[] args){HeaterSubject subject = new HeaterSubject();//订阅发出警报subject.OnBoilEvent += new AlertObserver().MakeAlert;//订阅显示水温subject.OnBoilEvent += new DisPlayObserver().Display;subject.BoilWater();}

 多播的优缺点

  1. 优点: 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。 被观察者发送通知,所有注册的观察者都会收到信息【可以实现广播机制】
  2. 缺点: 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃

 使用场景

  1. 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  2. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时。

 

相关文章:

c#设计模式-行为型模式 之 观察者模式

定义&#xff1a; 又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者 对象同时监听某一个主题对象。这个主题对象在状态变化时&#xff0c;会通知所有的观察者对象&#xff0c;使他们能够自 …...

开窗积累之学习更新版

1. 开窗使用1之 count range between current row and current row 将相同排序字段的值进行函数计算 selectsku_id,substr(create_date,1,7) date_month,order_id,create_date,sku_num*price,sum(sku_num*price) over (partition by sku_id order by substr(create_date,1,7)…...

ffplay简介

本文为相关课程的学习记录&#xff0c;相关分析均来源于课程的讲解&#xff0c;主要学习音视频相关的操作&#xff0c;对字幕的处理不做分析 ffplay播放器的意义 ffplay.c是FFmpeg源码⾃带的播放器&#xff0c;调⽤FFmpeg和SDL API实现⼀个⾮常有⽤的播放器。 ffplay实现了播…...

mysql之limit语句详解

一、介绍 LIMIT是MySQL内置函数&#xff0c;其作用是用于限制查询结果的条数。 二、使用 1. 语法格式 LIMIT [位置偏移量,] 行数 其中&#xff0c;中括号里面的参数是可选参数&#xff0c;位置偏移量是指MySQL查询分析器要从哪一行开始显示&#xff0c;索引值从0开始&#xff…...

4.while循环

1、while语句的语法结构如下&#xff1a; while语句可以在条件表达式为真的前提下&#xff0c;循环执行指定的一段代码&#xff0c;直到表达式不为真时结束循环。 1.1while语法结构 while(条件表达式){// 循环体} 执行思路&#xff1a; 1、执行思路 当条件表达式结果为tru…...

【雕爷学编程】 MicroPython动手做(35)——体验小游戏2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

mouseover 和 mouseenter

mouseover 和 mouseenter 事件是 JavaScript 中常用的两个鼠标事件&#xff0c;它们有一些区别&#xff1a; 触发条件: mouseover 事件在鼠标指针从元素外部进入元素内部时触发&#xff0c;包括子元素。换句话说&#xff0c;只要鼠标进入元素或其子元素&#xff0c;就会触发 mo…...

[JavaScript游戏开发] 绘制Q版地图、键盘上下左右地图场景切换

系列文章目录 第一章 2D二维地图绘制、人物移动、障碍检测 第二章 跟随人物二维动态地图绘制、自动寻径、小地图显示(人物红点显示) 第三章 绘制冰宫宝藏地图、人物鼠标点击移动、障碍检测 第四章 绘制Q版地图、键盘上下左右地图场景切换 文章目录 系列文章目录前言一、本章节…...

CI/CD持续集成持续发布(jenkins)

1.背景 在实际开发中&#xff0c;我们经常要一边开发一边测试&#xff0c;当然这里说的测试并不是程序员对自己代码的单元测试&#xff0c;而是同组程序员将代码提交后&#xff0c;由测试人员测试&#xff1b; 或者前后端分离后&#xff0c;经常会修改接口&#xff0c;然后重新…...

Qt5.14.2+QtCreator+PDB 查看源码

1. 在Creator添加源码 2. 安装PDB文件 Qt下载时没有整合最新的PDB文件下载&#xff0c;如果没有安装PDB文件&#xff0c;即使安装了src也无法调试。 双击MaintenanceTool.exe->设置->资料档案库->临时资料档案库->添加按钮&#xff0c;添加如下下载源&#xff1a…...

DOM基础获取元素+事件基础+操作元素

一.DOM简介 DOM&#xff0c;全称“Document Object Model&#xff08;文档对象模型&#xff09;”&#xff0c;它是由W3C定义的一个标准。 在实际开发中&#xff0c;我们有时候需要实现鼠标移到某个元素上面时就改变颜色&#xff0c;或者动态添加元素或者删除元素等。其实这些效…...

MATLAB——感知神经网络学习程序

学习目标&#xff1a;从学习第一个最简单的神经网络案例开启学习之路 感知器神经网络 用于点的分类 clear all; close all; P[0 0 1 1;0 1 0 1]; %输入向量 T[0 1 1 1]; %目标向量 netnewp(minmax(P),1,hardlim,lea…...

SpringBoot中事务失效的原因

SpringBoot中事务失效的原因 文章目录 SpringBoot中事务失效的原因一、事务方法非public修饰二、非事务方法调用事务方法三、事务方法的异常被捕获四、事务异常类型不对五、事务传播行为不对六、没有被Spring管理6.1、暴漏代理对象6.2、使用代理对象 常见的事务失效原因包括如下…...

Webstorm的一些常用快捷键

下面是Webstorm的一些常用快捷键&#xff1a; ctrl shift n: 打开工程中的文件&#xff0c;目的是打开当前工程下任意目录的文件。ctrl j: 输出模板ctrl b: 跳到变量申明处ctrl alt T: 围绕包裹代码(包括zencoding的Wrap with Abbreviation)ctrl []: 匹配 {}[]ctrl F1…...

系统集成项目成本管理

在项目中&#xff0c;成本是指项目活动或其组成部分的货币价值或价格&#xff0c;包括为实施、完成或创造该活动或其组成部分所需资源的货币价值。具体的成本一般包括直接工时、其他百接费用、间接工时、其他间接费用以及采购价格。 项目全过程所耗用的各种成本的总和为项目成本…...

Spring Boot整合ES的两种方式

使用Spring Data Elasticsearch Starter 在Spring Boot中整合Elasticsearch的方式之一是使用Elasticsearch的官方Spring Data Elasticsearch Starter。该Starter提供了对Elasticsearch的高级集成&#xff0c;简化了配置和管理Elasticsearch客户端。 下面是使用Spring Data E…...

Ajax_3 Ajax原理+ (XMLHttpRequest + Promise )+ 封装一个axios插件库,实现功能。

Ajax_3 Ajax原理 01-Ajax原理-XMLHttpRequest 使用XMLHttpRequest 步骤&#xff1a; 创建XMLHttpRequest对象配置请求方法请求url网址监听loadend事件&#xff0c;接受响应结果发起请求 需求&#xff1a;使用XMLHttpRequest对象与服务器通信 代码示例 // 1. 创建 XMLHttpReq…...

计算机网络(7) --- UDP协议和TCP协议

计算机网络&#xff08;6&#xff09; --- https协议_哈里沃克的博客-CSDN博客https协议https://blog.csdn.net/m0_63488627/article/details/132112683?spm1001.2014.3001.5501 目录 1.补充知识 1.PORT端口号 2.端口号范围划分 3.知名端口号 2.UDP协议 1.UDP报头 2.U…...

Jenkins 修改默认管理员帐号

1、新增一个新的超级管理员用户&#xff0c;并验证能正常登录 2、进入 Jenkins 用户管理目录&#xff1a; /data/software/jenkins/users 3、修改超级管理文件夹的名称为其他名称&#xff0c;如&#xff1a;mv admin_*** ifadm_*** 4、重启Jenkins容器...

FK-坦克大战制作(一)菜单制作

1、Cocos Creator新建2d项目 2.在资源管理器中新建场景menu 新建scences文件夹》新建场景》改名为menu 3.在层级管理器的Canvas下新建Layout节点&#xff0c;并在此节点下新建Label标签 4.双击Label&#xff0c;在属性检查器中进行编辑 5. 添加动画&#xff1a;(对文本进行放大…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...