C#设计模式(行为型模式):观察者模式
C#设计模式:观察者模式,让对象间通信更优雅
在软件开发中,我们经常会遇到一个对象的状态发生改变,其他对象需要自动更新或做出相应反应的场景。例如:
- GUI事件处理: 当用户点击按钮时,按钮需要通知所有注册的事件处理程序。
- 股票价格更新: 当股票价格发生变化时,所有关注该股票的投资者都需要收到通知。
- 气象站数据更新: 当气象站收集到新的气象数据时,所有显示气象数据的设备都需要更新显示。
为了实现这种对象间的通信,我们可以使用观察者模式(Observer Pattern),它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象的状态发生改变时,所有依赖于它的观察者对象都会收到通知并自动更新。
一、观察者模式简介
观察者模式属于行为型设计模式,它主要解决的是对象间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
二、观察者模式的结构
观察者模式包含四个角色:
- Subject(主题): 被观察的对象,它维护一个观察者列表,并提供注册、删除和通知观察者的方法。
- Observer(观察者): 定义了一个更新接口,用于接收主题的通知。
- ConcreteSubject(具体主题): 具体被观察的对象,它维护自身状态,并在状态改变时通知所有观察者。
- ConcreteObserver(具体观察者): 具体的观察者对象,它实现更新接口,并在收到通知时更新自身状态。
三、C# 实现示例
让我们通过一个简单的气象站示例来理解观察者模式:
// 主题接口
interface ISubject
{void RegisterObserver(IObserver observer);void RemoveObserver(IObserver observer);void NotifyObservers();
}// 观察者接口
interface IObserver
{void Update(float temperature, float humidity, float pressure);
}// 具体主题:气象站
class WeatherStation : ISubject
{private List<IObserver> _observers = new List<IObserver>();private float _temperature;private float _humidity;private float _pressure;public void RegisterObserver(IObserver observer){_observers.Add(observer);}public void RemoveObserver(IObserver observer){_observers.Remove(observer);}public void NotifyObservers(){foreach (var observer in _observers){observer.Update(_temperature, _humidity, _pressure);}}public void SetMeasurements(float temperature, float humidity, float pressure){_temperature = temperature;_humidity = humidity;_pressure = pressure;NotifyObservers();}
}// 具体观察者:显示当前天气状况
class CurrentConditionsDisplay : IObserver
{private float _temperature;private float _humidity;public void Update(float temperature, float humidity, float pressure){_temperature = temperature;_humidity = humidity;Display();}public void Display(){Console.WriteLine($"Current conditions: {_temperature}F degrees and {_humidity}% humidity");}
}// 客户端代码
class Program
{static void Main(string[] args){WeatherStation weatherStation = new WeatherStation();CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();weatherStation.RegisterObserver(currentDisplay);weatherStation.SetMeasurements(80, 65, 30.4f);weatherStation.SetMeasurements(82, 70, 29.2f);weatherStation.SetMeasurements(78, 90, 29.2f);}
}
四、观察者模式的优缺点
优点:
- 松耦合: 主题和观察者之间是松耦合的,主题不需要知道观察者的具体类,只需要知道观察者实现了更新接口。
- 可扩展性: 可以方便地增加新的观察者,而不需要修改主题的代码。
- 支持广播通信: 主题可以一次通知所有观察者。
缺点:
- 可能导致性能问题: 如果观察者数量很多,通知所有观察者可能会比较耗时。
- 可能导致内存泄漏: 如果观察者没有正确地从主题中注销,可能会导致内存泄漏。
五、总结
观察者模式提供了一种优雅的方式来实现对象间的一对多依赖关系,它在需要实现事件处理、数据更新等场景时非常有用。但是,在使用观察者模式时,也需要考虑其潜在的性能问题和内存泄漏问题。
希望这篇博客能帮助你更好地理解和使用观察者模式!
相关文章:
C#设计模式(行为型模式):观察者模式
C#设计模式:观察者模式,让对象间通信更优雅 在软件开发中,我们经常会遇到一个对象的状态发生改变,其他对象需要自动更新或做出相应反应的场景。例如: GUI事件处理: 当用户点击按钮时,按钮需要…...
pytorch镜像源
我以为的 pip install torch2.3.1cu118 torchvision0.18.1cu118 torchaudio2.3.1cu118 -f https://download.pytorch.org/whl/torch_stable.html实际上,有很多加速方案 为提高下载速度可以使用国内的镜像源来安装与 CUDA 11.8 兼容的 PyTorch。 方法 1:…...

Verilog语法之常用行为级语法
摘要:本文主要介绍了一些在verilog中的行为级语法,并且提供了大量的运行实际例子,可以通过这些例子感受行为级语法在仿真中的巨大作用。 概述:行为级语法是RTL级的上一层,或者说是比RTL级更高级的语法,其语…...

PADS Logic原理图中有很多页原理图,如何(怎样)删除其中一页或者多页
我们在进行PADS Logic进行原理图设计的时候,有时候可能遇到一次性设计了很多页的原理图,比如说十几页的原理图。那么我们在进行PADS Layout的时候,可能将这些原理图绘制两块板或者多块PCB板,那么这时候我们需要将其中的一张原理图…...

蓝色简洁引导页网站源码
一款蓝色的简洁引导页,适合资源分发和网站备用引导。 1.源码上传至虚拟机或者服务器 2.绑定域名和目录 3.访问域名安装 4.安装完成后就行了 https://pan.quark.cn/s/b2d8b9c5dc7f https://pan.baidu.com/s/17h1bssUNhhR9DMyNTc-i9Q?pwd84sf https://caiyun.139.com…...
Apache PDFBox添加maven依赖,pdf转成图片
要使用Apache PDFBox将PDF文件转换为图片,并将其添加到Maven项目中,您可以按照以下步骤操作: 1. 添加Maven依赖 在您的pom.xml文件中添加Apache PDFBox的依赖。请确保使用最新版本的PDFBox库。截至2025年,以下是推荐的配置&…...

mybatis 和 mybatisPlus 兼容性问题
项目采用的是 mybatis, 后续引入了 mybatisPlus,用 mybatisX 创建的四个类一直报错,提示找不到符号,意识到 mybatis 和 mybatisPlus 的兼容性问题,通过修改配置 两者的配置如下 #配置mybatis配置 mybatis:type-aliase…...
Mono里运行C#脚本23—mono_jit_exec
前面已经分析一部分代码,可以打下基础知识,当然还有很多其它部分的内容,没有深入去了解。 接着下来,我们去探索一下怎么样找到执行应用程序的入口。 在这个嵌入脚本程序里,有一个这样的函数调用: main_function (domain, file, argc - 1, argv + 1); 这个函数的作用,…...

第十一章 图论
/* * 题目名称:连通图 * 题目来源:吉林大学复试上机题 * 题目链接:http://t.cn/AiO77VoA * 代码作者:杨泽邦(炉灰) */#include <iostream> #include <cstdio>using namespace std;const int MAXN 1000 10;int fathe…...

纯前端实现将pdf转为图片(插件pdfjs)
需求来源 预览简历功能在移动端,由于用了一层iframe把这个功能嵌套在了app端,再用一个iframe来预览,只有ios能看到,安卓就不支持,查了很多资料和插件,原理基本上都是用iframe实现的。最终转换思路…...

【IT人物系列】之MySQL创始人
前言 当今世界有无数的人构成,其中有些人做了一些改变世界的事情,比如:乔布斯缔造了Apple帝国,詹姆斯高斯林创造了Java语言等。正是这些优秀的人做的这些优秀的事情,让这个世界更加美好。因此他们值得铭记。 从今天…...

在Typora中实现自动编号
文章目录 在Typora中实现自动编号1. 引言2. 准备工作3. 自动编号的实现3.1 文章大纲自动编号3.2 主题目录(TOC)自动编号3.3 文章内容自动编号3.4 完整代码 4. 应用自定义CSS5. 结论 在Typora中实现自动编号 1. 引言 Typora是一款非常流行的Markdown编辑…...

Single Shot MultiBox Detector(SSD)
文章目录 摘要Abstract1. 引言2. 框架2.1 网络结构2.2 损失函数2.3 训练细节 3. 创新点和不足3.1 创新点3.2 不足 参考总结 摘要 与Faster R-CNN相比,SSD是一个真正的单阶段多目标检测模型,同时也是一个全卷积网络,不仅检测准确率高ÿ…...

kafka生产者专题(原理+拦截器+序列化+分区+数据可靠+数据去重+事务)
目录 生产者发送数据原理参数说明代码示例(同步发送数据)代码示例(异步) 异步和同步的区别同步发送定义与流程特点 异步发送定义与流程特点 异步回调描述代码示例 拦截器描述代码示例 消息序列化描述代码示例(自定义序…...

【React+TypeScript+DeepSeek】穿越时空对话机
引言 在这个数字化的时代,历史学习常常给人一种距离感。教科书中的历史人物似乎永远停留在文字里,我们无法真正理解他们的思想和智慧。如何让这些伟大的历史人物"活"起来?如何让历史学习变得生动有趣?带着这些思考&…...

公共数据授权运营系统建设手册(附下载)
在全球范围内,许多国家和地区已经开始探索公共数据授权运营的路径和模式。通过建立公共数据平台,推动数据的开放共享,促进数据的创新应用,不仅能够提高政府决策的科学性和公共服务的效率,还能够激发市场活力࿰…...

基于HTML和CSS的旅游小程序
一、技术基础 HTML(HyperText Markup Language):超文本标记语言,用于定义网页的内容和结构。在旅游小程序中,HTML用于搭建页面的基本框架,包括标题、段落、图片、链接等元素,以及用于交互的表单…...

maven之插件调试
当使用maven进行项目管理的时候,可能会碰到一些疑难问题。网上资料很少,可能会想着直接调试定位问题。这里以maven-compiler-plugin为例: (1)准备maven-compiler-plugin源码 进入maven 官网-》Maven Plugins-》找到对…...
SQL Sever 数据库损坏,只有.mdf文件,如何恢复?
SQL Sever 数据库损坏,只有.mdf文件,如何恢复 在SQL Server 2008中,如果只有MDF文件而没有LDF文件,附加数据库的过程会稍微复杂一些。以下是几种可能的方法 一、使用紧急模式重建日志文件 1、新建一个同名的数据库。 2、停止SQ…...

【AWS SDK PHP】This operation requests `sigv4a` auth schemes 问题处理
使用AWS SDK碰到的错误,其实很简单,要装个扩展库 保持如下 Fatal error: Uncaught Aws\Auth\Exception\UnresolvedAuthSchemeException: This operation requests sigv4a auth schemes, but the client currently supports sigv4, none, bearer, sigv4-…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
【2D与3D SLAM中的扫描匹配算法全面解析】
引言 扫描匹配(Scan Matching)是同步定位与地图构建(SLAM)系统中的核心组件,它通过对齐连续的传感器观测数据来估计机器人的运动。本文将深入探讨2D和3D SLAM中的各种扫描匹配算法,包括数学原理、实现细节以及实际应用中的性能对比,特别关注…...
Neo4j 完全指南:从入门到精通
第1章:Neo4j简介与图数据库基础 1.1 图数据库概述 传统关系型数据库与图数据库的对比图数据库的核心优势图数据库的应用场景 1.2 Neo4j的发展历史 Neo4j的起源与演进Neo4j的版本迭代Neo4j在图数据库领域的地位 1.3 图数据库的基本概念 节点(Node)与关系(Relat…...

NLP学习路线图(三十四): 命名实体识别(NER)
一、命名实体识别(NER)是什么? 命名实体识别(Named Entity Recognition, NER)是自然语言处理中的一项关键序列标注任务。其核心目标是从非结构化的文本中自动识别出特定类别的名词性短语,并将其归类到预定义的类别中。 核心目标:找到文本中提到的命名实体,并分类。 典…...