当前位置: 首页 > 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;(对文本进行放大…...

Adobe-GenP 3.0:解锁Adobe全家桶功能的5分钟终极指南 [特殊字符]

Adobe-GenP 3.0&#xff1a;解锁Adobe全家桶功能的5分钟终极指南 &#x1f680; 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP Adobe-GenP 3.0是一款强大的Adobe C…...

AI法律助手:基于RAG与LLM的垂直领域应用实践

1. 项目概述&#xff1a;当AI遇见法律&#xff0c;一个开源法律助手的诞生最近在GitHub上看到一个挺有意思的项目&#xff0c;叫imyuanx/ai-lawyer。光看名字&#xff0c;你大概就能猜到它的方向——一个AI驱动的法律助手。作为一名在技术和应用交叉领域摸爬滚打多年的从业者&a…...

OpenClaw用户如何通过Taotoken获得更优的模型调用体验

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 OpenClaw用户如何通过Taotoken获得更优的模型调用体验 对于使用OpenClaw构建智能体工作流的开发者而言&#xff0c;直接对接多个大…...

告别命令行恐惧!Mac上这款Fork Git客户端,让代码提交像聊天一样简单

告别命令行恐惧&#xff01;Mac上这款Fork Git客户端&#xff0c;让代码提交像聊天一样简单 第一次接触Git时&#xff0c;面对黑底白字的终端窗口输入git commit -m "fix bug"的场景&#xff0c;很多人都会感到一阵眩晕。命令行就像一堵高墙&#xff0c;把非计算机科…...

树莓派SPI驱动TFT显示屏:从硬件连接到Python图形编程实战

1. 项目概述与核心价值如果你手头有一块闲置的树莓派&#xff0c;想给它配个小屏幕做个状态监控器、迷你信息站&#xff0c;或者DIY一个便携游戏机&#xff0c;那么连接一块TFT显示屏几乎是必经之路。但当你真正动手时&#xff0c;可能会被一堆引脚、SPI、驱动芯片这些术语搞得…...

Mac上编译C语言的简易方法

1、 null 2、 在 Mac OS X 系统中&#xff0c;可通过 Xcode 学习和编写 C 语言程序。 3、 在Xcode中运行C语言程序需先创建项目&#xff0c;然后在项目中添加源代码文件。 4、 启动 Xcode&#xff0c;点击创建新项目以新建一个工程&#xff0c;具体操作所示。 5、 选择需创建…...

Chapter 13:企业实战 - 完整案例演练

Chapter 13:企业实战 - 完整案例演练 学习目标 掌握从需求分析到落地实施的完整流程 能够综合运用 Rules、Skills、MCP、Subagent 理解企业级项目的完整解决方案设计 具备独立设计企业扩展方案的能力 概念讲解(Why) 1.1 实战演练概述 案例背景: 某电商公司"极速商…...

保姆级避坑指南:用GGCNN源码搞定Cornell抓取数据集转换(附.mat/.tiff生成全流程)

保姆级避坑指南&#xff1a;用GGCNN源码搞定Cornell抓取数据集转换全流程 当你第一次尝试复现GGCNN这个经典的机器人抓取项目时&#xff0c;Cornell数据集的预处理往往会成为第一个拦路虎。作为一个曾经在这个环节卡了整整两天的过来人&#xff0c;我深知那些官方文档没写的细节…...

uniApp H5项目从打包到上线:一站式解决跨域与Nginx部署

1. uniApp H5项目打包全流程解析 第一次用uniApp打包H5项目时&#xff0c;我对着空白页面和404错误整整折腾了两天。后来才发现&#xff0c;问题出在基础路径配置这个看似简单的环节上。uniApp打包H5和传统Vue项目有些不同&#xff0c;这里我把踩过的坑都总结成可复用的经验。 …...

ARM PMU性能监控架构与PMCEID2寄存器详解

1. ARM PMU性能监控架构概述性能监控单元(Performance Monitoring Unit, PMU)是现代处理器中用于硬件级性能分析的核心模块。在ARM架构中&#xff0c;PMU通过一组可编程的事件计数器实现对处理器微架构行为的精确监控。这些计数器可以记录诸如指令执行周期、缓存命中/失效、分支…...