.NET 设计模式—观察者模式(Observer Pattern)

简介

在.NET中,观察者模式是一种设计模式,它允许对象之间进行一对多的依赖关系。当一个对象的状态发生变化时,所有依赖于它的对象都会收到通知并自动更新。这种模式在事件驱动的设计中非常常见。

在.NET中实现观察者模式,通常涉及到定义一个抽象的观察者接口和一个可被观察的对象。这个可被观察的对象维护一个观察者的列表,并在状态改变时通知所有观察者。

角色

  • 抽象主题角色(Subject):抽象主题把所有观察者对象的引用保存在一个列表中,并提供增加和删除观察者对象的操作,抽象主题角色又叫做抽象被观察者角色,一般由抽象类或接口实现。
  • 抽象观察者角色(Observer):为所有具体观察者定义一个接口,在得到主题通知时更新自己,一般由抽象类或接口实现。
  • 具体主题角色(ConcreteSubject):实现抽象主题接口,具体主题角色又叫做具体被观察者角色。
  • 具体观察者角色(ConcreteObserver):实现抽象观察者角色所要求的接口,以便使自身状态与主题的状态相协调。

优点

  • 观察者模式实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层,即观察者。
  • 观察者模式在被观察者和观察者之间建立了一个抽象的耦合,被观察者并不知道任何一个具体的观察者,只是保存着抽象观察者的列表,每个具体观察者都符合一个抽象观察者的接口。
  • 观察者模式支持广播通信。被观察者会向所有的注册过的观察者发出通知。

缺点

  • 如果一个被观察者有很多直接和间接的观察者时,将所有的观察者都通知到会花费很多时间。
  • 虽然观察者模式可以随时使观察者知道所观察的对象发送了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎样发生变化的。
  • 如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃,在使用观察者模式应特别注意这点。

应用场景

  • 当需要将一个对象的状态变化通知给其他多个对象时,可以使用观察者模式;
  • 当一个对象的改变需要同时改变其他对象的状态或者操作时,可以使用观察者模式;
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时,可以使用观察者模式。例如,模型和视图之间的关系,模型驱动视图的更新,而视图反过来也要反映到模型中;
  • 当一个对象必须通知其他对象,但是你不知道这些对象是谁时,可以使用观察者模式。例如,你不知道哪些用户订阅了你的微信公众号,但你需要在每次发布新文章时通知所有订阅用户;
  • 当一个对象需要有别的对象来协助完成某项工作,并且不希望知道具体协助它的对象时,可以使用观察者模式。例如,一个员工完成某项任务需要得到经理的批准,但他并不知道具体是哪个经理会批准。

实现

  • 定义观察者接口
public interface IObserver
{void Update(string message); // 或者根据具体需求定义其他方法
}
  • 定义可观察的对象,它包含一个观察者列表,并提供注册和通知观察者的方法
using System.Collections.Generic;public class Observable
{private List<IObserver> observers = new List<IObserver>();private string state;// 注册观察者public void RegisterObserver(IObserver observer){observers.Add(observer);}// 移除观察者(可选)public void RemoveObserver(IObserver observer){observers.Remove(observer);}// 通知所有观察者(状态改变时调用)protected void NotifyObservers(string message){foreach (var observer in observers){observer.Update(message);}}// 改变状态并通知观察者(这里假设状态是一个字符串)public void ChangeState(string newState){state = newState;NotifyObservers("State changed to: " + state); // 通知所有观察者状态已改变及新状态信息}
}
  • 实现具体的观察者类,它实现观察者接口并定义如何响应通知
public class ConcreteObserver : IObserver
{public void Update(string message){// 在这里处理接收到的通知,比如更新UI、记录日志等操作。Console.WriteLine("Observer received: " + message); // 仅作为示例,实际实现根据需求来定。}
}
  • 上层应用调用
class Program
{static void Main(string[] args){// 创建可观察对象和观察者实例。Observable observable = new Observable();ConcreteObserver observer = new ConcreteObserver(); // 可以创建多个观察者实例。observable.RegisterObserver(observer); // 注册观察者到可观察对象。// ... 在程序的其他部分,当需要通知观察者时调用可观察对象的ChangeState方法     observable.ChangeState("New state information");。这样就会触发通知所有注册的观察者。}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/309381.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.MMD模型动作场景镜头的导入及视频导出

界面介绍 MIKUMIKUDANCE926版本 MMD的工具栏模型骨骼帧的窗口&#xff0c;在不同时间做不同动作&#xff0c;可以在这里打帧操作时间曲线操作窗口&#xff0c;控制模型两个动作之间的过渡模型操作窗口&#xff0c;导入模型选择模型相机操作&#xff0c;控制相机远近&#xf…

详解拷贝构造

拷贝构造的功能 写法&#xff1a; 拷贝构造函数的参数为什么是引用类型 系统自动生成的拷贝构造函数 拷贝构造的深拷贝与浅拷贝 概念 浅拷贝&#xff1a; 深拷贝 小结 拷贝构造的功能 拷贝构造函数可以把曾经实例化好的对象的数据拷贝给新创建的数据 &#xff0c;可见…

计算机网络常问面试题

一.HTTPS是如何保证安全传输的 https通过使⽤对称加密、⾮对称加密、数字证书等⽅式来保证数据的安全传输。 客户端向服务端发送数据之前&#xff0c;需要先建⽴TCP连接&#xff0c;所以需要先建⽴TCP连接&#xff0c;建⽴完TCP连接后&#xff0c;服务端会先给客户端发送公钥…

LabVIEW直流稳定电源自动化校准系统

LabVIEW直流稳定电源自动化校准系统 直流稳定电源正向着智能化、高精度、多通道、宽量程的方向发展。基于LabVIEW开发环境&#xff0c;设计并实现了一种直流稳定电源自动化校准系统&#xff0c;以提升校准过程的整体效能&#xff0c;实现自动化设备替代人工进行电源校准工作。…

MYSQL执行过程和顺序详解

一、前言 1.1、说明 就MySQL在执行过程、sql执行顺序&#xff0c;以及一些相关关键字的注意点方面的学习分享内容。 在参考文章的基础上&#xff0c;会增加自己的理解、看法&#xff0c;希望本文章能够在您的学习中提供帮助。 如有错误的地方&#xff0c;欢迎指出纠错&…

SHARE 203S PRO:倾斜摄影相机在地灾救援中的应用

在地质灾害的紧急关头&#xff0c;救援队伍面临的首要任务是迅速而准确地掌握灾区的地理信息。这时&#xff0c;倾斜摄影相机成为了救援测绘的利器。SHARE 203S PRO&#xff0c;这款由深圳赛尔智控科技有限公司研发的五镜头倾斜摄影相机&#xff0c;以其卓越的性能和功能&#…

【Python】使用OPC UA创建数据服务器

目录 准备工作服务器设置创建或获取节点设置节点值启动服务器查看服务器客户端总结 在工业自动化和物联网&#xff08;IoT&#xff09;领域&#xff0c;OPC UA&#xff08;开放平台通信统一架构&#xff09;已经成为一种广泛采用的数据交换标准。它提供了一种安全、可靠且独立于…

网络篇10 | 网络层 IP

网络篇10 | 网络层 IP 01 简介02 名称解释03 IP报文格式(IPv4)1&#xff09;4位版本协议(version)2&#xff09;4位首部长度(header length)3&#xff09;8位服务类型(Type Of Service, TOS)4&#xff09;16位总长度5&#xff09;16位(分片)标识6&#xff09;3位(分片)标志7&am…

基于docker的开发者集成环境

docker-compose一键部署开发者环境。 常见的中间件&#xff1a;nginx, mysql, redis, mongo, rabbitmq, nacos, rocketmq, zookeeper等。 GIthub项目地址 1. 下载项目&#xff1a;git clone https://github.com/xhga/docker-develop-env.git 2. 进入文件夹&#xff1a;cd d…

有关“海口双日晕”现象的闲扯

今&#xff08;4月14日&#xff09;天&#xff0c;人民微博、海南广播电视总台、海南日报、人民视觉等官媒&#xff0c;争相报道“海口上空出现双日晕”这则新闻。本“人民体验官”&#xff0c;现在特别推广人民日报官方微博文化产品《海口双日晕&#xff01;美好加倍&#xff…

【无向图找环】网格树

题目 #include<bits/stdc.h> using namespace std; #define int long long #define fi first #define se second const int maxn 2e5 5; const int inf 1e9 5;using namespace std;int n, m; //int pre[maxn]; int a[30][30], b[30][30];int dx[] {-1, 1, 0, 0}, dy…

llamafactory:unified efficient fine-tuning of 100+ lanuage models

1.introduction llamafactory由三个主要模块组成&#xff0c;Model Loader&#xff0c;Data Worker&#xff0c;Trainer。 2.Efficient fine-tuning techniques 2.1 Efficient Optimization 冻结微调&#xff1a;冻结大部分参数&#xff0c;同时只在一小部分解码器层中微调剩…

Echarts简单的多表联动效果和添加水印和按钮切换数据效果

多表联动 多表联动效果指的是在多个表格之间建立一种交互关系&#xff0c;以便它们之间的操作或选择能够相互影响。通常情况下&#xff0c;多表联动效果可以通过以下方式之一实现&#xff1a; 数据关联&#xff1a; 当在一个表格中选择或操作某些数据时&#xff0c;另一个表格…

一.NODE MCU(ESP8285,ESP8286)开发环境搭建

一.序言: 1.esp8285长什么样? 2.esp8285是什么,能做什么? 通过上面图片,看到上面的芯片,是带有多个阵脚的单片机。实际上,看着该芯片很小,但是却具有完整的wifi无线蓝牙功能,它本身可以运行一个极简的linux小系统,并且该极简的小linux系统具备无线蓝牙功能。。它同…

网络编程【InetAddress , TCP 、UDP 、HTTP 案例】

day38上 网络编程 InetAddress 理解&#xff1a;表示主机类 一个域名 对应 多个IP地址 public static void main(String[] args) throws UnknownHostException {//获取本机的IP地址 // InetAddress localHost InetAddress.getLocalHost(); // System.out.println(localHos…

Mac 软件清单

~自留备用~ Macbook用了几年之后, 512G的内置硬盘有些紧张了, 这几天总是提示空间不足, 就重装了下系统, 重装之后竟然不记得有些软件的名字和下载链接, 特此记录 Office 办公套件 直接从微软官网下载Office 安装包https://officecdnmac.microsoft.com/pr/C1297A47-86C4-4C1F…

python botos s3 aws

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html AWS是亚马逊的云服务&#xff0c;其提供了非常丰富的套件&#xff0c;以及支持多种语言的SDK/API。本文针对其S3云储存服务的Python SDK&#xff08;boto3&#xff09;的使用进行介绍。 …

golang 使用栈模拟计算器

思路&#xff1a; // Author sunwenbo // 2024/4/12 16:51 package mainimport ("errors""fmt""strconv" )// 使用数组来模拟一个栈的应用 type Stack struct {MaxTop int //表示栈最大可以存放数的个数Top int //表示栈底&#xff…

了解 Vue 工程化开发中的组件通信

目录 1. 组件通信语法 1.1. 什么是组件通信&#xff1f; 1.2. 为什么要使用组件通信&#xff1f; 1.3. 组件之间有哪些关系&#xff08;组件关系分类&#xff09;&#xff1f; 1.4. 组件通信方案有哪几类 &#xff1f; 2. 父子通信流程图 3. 父传子 3.1. 父传子核心流程…

Tool:VRAM的简介、查询电脑VRAM的常用方法

Tool&#xff1a;VRAM的简介、查询电脑VRAM的常用方法 目录 VRAM的简介 查询电脑VRAM的常用方法 1、对于Windows系统 T1、设置-系统-显示查询法 T2、使用 DirectX 诊断工具&#xff1a; T3、使用系统信息工具&#xff1a; 2、对于Linux系统 T1、使用nvidia-smi命令&…