C# 基于事件的观察者模式
观察者模式是一种软件设计模式,用于定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,它的所有依赖者(观察者)都将得到通知并自动更新。这种模式通过解耦合主题和观察者来提高对象的灵活性。
定义
观察者模式包括一个主题(Subject)和多个观察者(Observer)。当主题的状态改变时,它会通知观察者并调用它们的特定方法,使得观察者可以自动更新。
应用场景
观察者模式常见于以下场景:
1. 当一个对象的变化需要通知其他对象,而且你无法确切知道有多少个对象需要通知时,可以使用观察者模式。
2. 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,这时使用观察者模式可以将这两者封装在独立的对象中,使它们各自独立地改变和复用。
优点
1. 观察者模式降低了主题和观察者之间的耦合度,使得主题和观察者可以轻松地独立变化。
2. 支持广播通信,观察者模式可以向多个对象同时发送通知。
缺点
1. 如果观察者过多或通知机制过于复杂,容易导致性能问题。
2. 如果观察者和主题之间存在循环依赖,可能会导致系统崩溃或出现死循环。
观察者模式是一种广泛应用的设计模式,在许多面向对象编程语言和框架中都有相应的实现,例如在事件处理、模型-视图-控制器 (MVC) 架构中都有观察者模式的影子。
Demo
1.Subject类
internal abstract class SubjectBase{// 将所有观察者放入list集合private readonly List<Observer> observers = new List<Observer>();public event EventHandler<EventArgs> NotifyAllHandler;public virtual void NotifyAllObserver(){NotifyAllHandler?.Invoke(this, EventArgs.Empty);}/// <summary>/// 加入集合/// </summary>/// <param name="observer"></param>public virtual void AttachObserver(Observer observer){observers.Add(observer);}/// <summary>/// 从观察者列表中去除/// </summary>/// <param name="observer"></param>public virtual void RemoveObserver(Observer observer){observers.Remove(observer);}}
internal class Subject: SubjectBase{}
2.Observer观察者抽象类
/// <summary>/// 观察者抽象类/// </summary>internal abstract class Observer{protected SubjectBase _subject;/// <summary>/// 更新消息/// </summary>public abstract void Update(object? sender, EventArgs eventArgs);public virtual void SetSubject(SubjectBase subject){if (subject == _subject) return;if (this._subject != null){this._subject.RemoveObserver(this);this._subject.NotifyAllHandler -= Update;}this._subject = subject;this._subject.AttachObserver(this);this._subject.NotifyAllHandler += Update;}}
3.具体观察者,需要继承Observer基类
internal class Observer_A : Observer{public override void Update(object? sender, EventArgs eventArgs){Console.WriteLine($"Observer_A");}}internal class Observer_B : Observer{public override void Update(object? sender, EventArgs eventArgs){Console.WriteLine($"Observer_B");}}
调用
// 发布类
SubjectBase subject = new Subject();// 观察者
Observer observerA = new Observer_A();
observerA.SetSubject(subject);
Observer observerB = new Observer_B();
observerB.SetSubject(subject);// 发布类间隔通知
await Task.Run(() =>
{while (true){subject.NotifyAllObserver();Console.WriteLine("====================================================");Thread.Sleep(3000);}
});
相关文章:
C# 基于事件的观察者模式
观察者模式是一种软件设计模式,用于定义对象之间的一对多依赖关系,当一个对象的状态发生变化时,它的所有依赖者(观察者)都将得到通知并自动更新。这种模式通过解耦合主题和观察者来提高对象的灵活性。 定义 观察者模式…...
ARM CCA机密计算软件架构之软件堆栈概述
Arm CCA平台通过硬件添加和固件组件的混合方式实现,例如在处理元素(PEs)中的RME以及特定的固件组件,特别是监视器和领域管理监视器。本节介绍Arm CCA平台的软件堆栈。 软件堆栈概述 领域VM的执行旨在与Normal world(正常世界)隔离,领域VM由Normal world Host(正常世界…...
《Python机器学习原理与算法实现》学习笔记
以下为《Python机器学习原理与算法实现》(杨维忠 张甜 著 2023年2月新书 清华大学出版社)的学习笔记。 根据输入数据是否具有“响应变量”信息,机器学习被分为“监督式学习”和“非监督式学习”。 “监督式学习”即输入数据中即有X变量&…...
k8s集群通过helm部署skywalking
1、安装helm 下载脚本安装 ~# curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 ~# chmod 700 get_helm.sh ~# ./get_helm.sh或者下载包进行安装 ~# wget https://get.helm.sh/helm-canary-linux-amd64.tar.gz ~# mv helm …...
介绍一款PDF在线工具
PDF是我们日常工作中的一种常见格式,其处理也是我们工作的重要基础性环节,一款可靠的处理工具显得十分重要。 完全免费、易于使用、丰富的PDF处理工具,包括:合并、拆分、压缩、转换、旋转和解锁PDF文件,以及给PDF文件…...
docker学习——汇总版
历时一个月将docker系统的学习了一下,并且记录了详细的笔记和实践过程。 希望能对工作需要的小伙伴们有所帮助~ docker基础篇 docker学习(一、docker与VM对比) docker学习(二、安装docker) docker学习(…...
百度沧海文件存储CFS推出新一代Namespace架构
随着移动互联网、物联网、AI 计算等技术和市场的迅速发展,数据规模指数级膨胀,对于分布式文件系统作为大规模数据场景的存储底座提出了更高的要求。已有分布式文件系统解决方案存在着短板,只能适应有限的场景: >> 新型分布式…...
16-网络安全框架及模型-BiBa完整性模型
目录 BiBa完整性模型 1 背景概述 2 模型原理 3 主要特性 4 优势和局限性 5 应用场景 BiBa完整性模型 1 背景概述 Biba完整性模型是用于保护数据完整性的模型,它的主要目标是确保数据的准确性和一致性,防止未授权的修改和破坏。在这个模型中&#…...
ssm基于冲突动态监测算法的健身房预约系统的设计与实现论文
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装健身房预约系统软件来发挥其高效地信息处理的作用ÿ…...
基于 Element UI 适用于 Vue 2 版本的虚拟列表选择器组件el-select
背景:在某些使用情况下,单个选择器可能最终加载数万行数据。 将这么多的数据渲染至 DOM 中可能会给浏览器带来负担,从而造成性能问题。 ——vue3element-plus有现成的轮子。而vue2element-ui没有。 以下 文章大部分 摘自 源组件中的README.md…...
java常见面试题:请解释一下Java中的常用分布式框架,如Spring Boot、Dubbo等。
下面我将详细介绍Java中的两个常用分布式框架:Spring Boot和Dubbo。 1. Spring Boot Spring Boot是一个用于创建独立、可运行的、生产级别的Spring应用程序的框架。它简化了Spring应用程序的创建和部署,使得开发人员能够专注于编写业务逻辑,…...
FreeRTOS列表与列表项相关知识总结以及列表项的插入与删除实战
1.列表与列表项概念及结构体介绍 1.1列表项简介 列表相当于链表,列表项相当于节点,FreeRTOS 中的列表是一个双向环形链表 1.2 列表、列表项、迷你列表项结构体 1)列表结构体 typedef struct xLIST { listFIRST_LIST_INTEGRITY_CHECK_VAL…...
07|输出解析:用OutputParser生成鲜花推荐列表
07|输出解析:用OutputParser生成鲜花推荐列表 模型 I/O Pipeline 下面先来看看 LangChain 中的输出解析器究竟是什么,有哪些种类。 LangChain 中的输出解析器 语言模型输出的是文本,这是给人类阅读的。但很多时候,你…...
cfa一级考生复习经验分享系列(十二)
背景:就职于央企金融机构,本科金融背景,一直在传统金融行业工作。工作比较忙,用了45天准备考试,几乎每天在6小时以上。 写在前面的话 先讲一下,整体一级考下来,我觉得知识点多,偏基础…...
【损失函数】SmoothL1Loss 平滑L1损失函数
1、介绍 torch.nn.SmoothL1Loss 是 PyTorch 中的一个损失函数,通常用于回归问题。它是 L1 损失和 L2 损失的结合,旨在减少对异常值的敏感性。 loss_function nn.SmoothL1Loss(reductionmean, beta1.0) 2、参数 size_average (已弃用): 以前用于确定是…...
Go语言中的HTTP重定向
大家好,我是你们可爱的编程小助手,今天我们要一起探讨如何使用Go语言实现HTTP重定向,让我们开始吧! 大家都知道,网站开发中有时候需要将用户的请求从一个URL导向到另一个URL。比如说,你可能想将旧的URL结构…...
ORACLE P6 v23.12 最新虚拟机(VM)全套系统环境分享
引言 根据上周的计划,我简单制作了两套基于ORACLE Primavera P6 最新发布的23.12版本预构建了虚拟机环境,里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机,请先与Oracle Primavera销售代…...
鸿蒙开发ArkTS基础学习-开发准备工具配置
文章目录 前言1. 准备工作2.开发文档3.鸿蒙开发路径一.详情介绍二.DevEco Studio安装详解-开发环境搭建2.1配置开发环境欢迎各位读者阅读本文,今天我们将介绍鸿蒙(HarmonyOS)应用开发的入门步骤,特别是在准备工作和开发环境搭建方面的重要信息。本文将对鸿蒙官方网站的关键…...
WEB 3D技术 three.js 雾 基础使用讲解
本文 我们说一下 雾 在three.js中有一个 Fog类 它可以创建线性雾的一个效果 她就是模仿现实世界中 雾的一个效果 你看到远处物体会组件模糊 直到完全被雾掩盖 在 three.js 中 有两种雾的形式 一种是线性的 一种是指数的 个人觉得 线性的会看着自然一些 他是 从相机位置开始 雾…...
Python中的网络编程
IP地址 IPv4IPv6查看本机的IP地址 win ipconfiglinux ifconfig ping命令 ping www.baidu.com 查看是否能连通指定的网站ping 192.168.1.222 查看是否能连通指定的IP Port端口 0-65535 TCP/IP协议 传输数据之前要建立连接,通过三次握手建立: 客户端 --&g…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...
华为云Flexus+DeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手
华为云FlexusDeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手 一、构建知识库问答助手引言二、构建知识库问答助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建知识库问答助手实战3.1 配置Dify环境3.2 创建知识库问答助手3.3 使用知…...
【动态规划】B4336 [中山市赛 2023] 永别|普及+
B4336 [中山市赛 2023] 永别 题目描述 你做了一个梦,梦里有一个字符串,这个字符串无论正着读还是倒着读都是一样的,例如: a b c b a \tt abcba abcba 就符合这个条件。 但是你醒来时不记得梦中的字符串是什么,只记得…...
