设计模式之观察者(发布订阅)模式

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同事监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己
在这里插入图片描述

  class Program{static void Main(string[] args){ConcreteSubject concreteSubject = new ConcreteSubject();concreteSubject.Attach(new ConcreteObserver(concreteSubject, "奶茶店"));concreteSubject.Attach(new ConcreteObserver(concreteSubject, "快餐店"));concreteSubject.Attach(new ConcreteObserver(concreteSubject, "花店"));concreteSubject.SubjectState = "顾客来了";concreteSubject.Notify();//消息通知Console.ReadLine();}}//抽象消息通知者,一般用一一个抽象类或者一个接口实现。它把所有对观察者对象的引用保存在一个容器里,每个消息通知者都可以联系任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象abstract class Subject{private IList<Observer> observers = new List<Observer>();//观察者列表//增加观察者public void Attach(Observer observer){observers.Add(observer);}//移除观察者public void Detach(Observer observer){observers.Remove(observer);}//将消息通知给所观察者public void Notify(){foreach (Observer o in observers){o.Update();}}}//抽象观察者,是所有观察者的基类,在得到消息发布者的消息后,使用更新方法更新自己的状态abstract class Observer{public abstract void Update();}//具体消息通知者,继承自Subject的具体类,将有关状态存入具体观察者对象;在具体消息通知者内部状态改变的时候,给所有在容器中的观察者发布消息。class ConcreteSubject : Subject{private string subjectState;//消息通知者的具体消息//具体被观察者状态public string SubjectState{get { return subjectState; }set { subjectState = value; }}}//具体观察者,实现抽象观察者的接口,以便本身的状态与消息通知者的状态相协调class ConcreteObserver : Observer{private string name;private string observerState;private ConcreteSubject subject;public ConcreteObserver(ConcreteSubject subject, string name){this.subject = subject;this.name = name;}public override void Update(){observerState = subject.SubjectState;Console.WriteLine("{0}的新状态是{1}",name,observerState);}public ConcreteSubject Subject{get { return subject; }set { subject = value; }}}

观察者模式主要解决的问题:当一个对象状态发生改变后给其他的对象通知

观察者的优点:
观察者和被观察者是抽象耦合的,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。

观察者的缺点:
1、如果一个被观察者对象有很多的直接或间接的观察者的话,消耗的时间会增加很多。

2、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅是知道被观察者发生变化,会有很一些不需要改变状态的观察者被迫发生状态改变。

3、如果观察者与被观察者之间有循环依赖,会造成陷入死循环中,导致系统崩溃。


观察者模式的变体—— 发布订阅模式

发布订阅模式需要引用到了事件与委托这个两种类型

委托
事件

订阅发布模式,发布者的消息发送者不会讲消息直接发送给订阅者,这意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心和中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地发布它们给订阅者。

优点
1、支持简单的广播通信,当对象状态发生改变时,会自动通知已经订阅过的对象
2、发布者与订阅者耦合性降低,发布者只管发布一条消息后,订阅者只监听发布者的事件名,只要发布者的事件名不变,它不管发布者如何改变

缺点
1、创建订阅者需要消耗一定时间的内存
2、增加维护的难度

区别与联系
联系:
订阅发布是观察者模式的一种变种。
区别:
1、观察模式中观察者和被观察者是松耦合的关系、发布-订阅模式中完全不存在耦合。
2、观察模式中观察者与被观察者相互感知,发布-订阅模式中存在中间调度工厂。

class Program{static void Main(string[] args){Client c1 = new Client();ObserverA a = new ObserverA("路北", c1);ObserverB b = new ObserverB("路南", c1);c1.Update += new Handler(a.Work);c1.Update += new Handler(b.Work);c1.SubjectState = "顾客";c1.Notify();}}interface Subject{public void  Notify();string SubjectState{get;set;}}delegate void Handler();//声明委托class Client : Subject{public event Handler Update;//声明Handler(事件处理程序)的委托事件Update方法private string action;public void Notify()//引发Update方法{Update();}public string SubjectState{get { return action; }set { action = value; }}}class ObserverA{private string name;private Subject subject;public ObserverA(string name, Subject subject){this.name = name;this.subject = subject;}public void Work(){Console.WriteLine("{0}来了,{1}开始工作",subject.SubjectState,name);}}class ObserverB{private string name;private Subject subject;public ObserverB(string name, Subject subject){this.name = name;this.subject = subject;}public void Work(){Console.WriteLine("{0}来了,{1}开始工作", subject.SubjectState, name);}}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

字符串函数

目录 一、求字符串长度 strlen 用法&#xff1a; 注意&#xff1a; 用例&#xff1a; 二、长度不受限制的字符串函数 strcpy 用法&#xff1a; 注意&#xff1a; 用例: strcat 用法&#xff1a; 注意&#xff1a; 用例&#xff1a; strcmp 用法&#xff1a; 三…

Vue系列(三)之 基础语法下篇【事件处理,表单综合案例,组件通信】

一. 事件处理 在 Vue.js 中&#xff0c;v-on 指令被用于监听 DOM 事件&#xff0c;并在事件触发时执行相应的方法&#xff0c;这些方法就是事件处理器。v-on 指令有简写形式 &#xff0c;例如 click"handleClick" 会监听点击事件并执行 handleClick 方法。 事件处理…

1小时掌握Python操作Mysql数据库之pymysql模块技术

大家好&#xff0c;我是python222小锋老师。前段时间卷了一套 Python3零基础7天入门实战 近日锋哥又卷了一波课程&#xff0c;Python操作Mysql数据库的pymysql技术&#xff0c;文字版视频版。1小时掌握。 视频版教程 1小时掌握Python操作Mysql数据库之pymysql模块技术 文字版…

RHCSA_Linux 从命令行管理文件

目录 一、文件命令规范&#xff1a; 二、创建链接文件 1、创建软链接文件 2、创建硬链接文件 三、目录操作命令 1、创建目录 -- mkdir 2、统计目录及文件的空间占用情况 -- du 3、删除目录文件 四、创建、删除普通文件 1、创建普通文件 2、删除普通文件 五、数据流和…

golang实现远程控制主机

文章目录 ssh原理使用golang远程下发命令使用golang远程传输文件 ssh原理 说到ssh原理个人觉得解释最全的一张图是这张华为画的 Connection establishment 这一步就是建立tcp连接 version negotiation 这一步是ssh客户端(连接者)和被ssh服务端(连接者)进行协议的交换&#xf…

Redis桌面管理工具Redis Desktop Manager mac中文版功能特色

Redis Desktop Manager for Mac是一款实用的Redis可视化工具。RDM支持SSL / TLS加密&#xff0c;SSH隧道&#xff0c;基于SSH隧道的TLS&#xff0c;为您提供了一个易于使用的GUI&#xff0c;可以访问您的Redis数据库并执行一些基本操作&#xff1a;将键视为树&#xff0c;CRUD键…

Springboot整合分页插件pagehelper

首先需要有一定的springbootmybatis的基础&#xff0c;才能使用顺畅 项目结构如下 引入依赖&#xff0c;springboot版本选的是2.7.16版本&#xff0c;jdk选的17&#xff0c; <!--分页插件--> <dependency><groupId>com.github.pagehelper</groupId><…

静态通讯录

今天我们分享一下静态通讯录详细解释和代码&#xff0c;之前分享过的只是通讯录的代码&#xff0c;但是我们没有进行讲解和解释&#xff0c;今天我们一边分享它的代码一边解释原因&#xff0c;让大家可以手撕通讯录。现在开始我们的学习吧。 首先我们应该要有三个文件&#xf…

java面试题-jvm基础知识

1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序的运行环境&#xff08;java二进制字节码的运行环境&#xff09; 好处&#xff1a; 一次编写&a…

计算机丢失msvcp140_1.dll的解决办法,丢失msvcp140_1.dll的原因

丢失 msvcp140_1.dll 是一个常见的错误信息&#xff0c;通常会在尝试运行某些程序时出现。msvcp140_1.dll 是一个动态链接库文件&#xff0c;它包含了许多 C标准库函数的实现&#xff0c;这些函数在许多程序中都是必需的。因此&#xff0c;如果丢失了该文件&#xff0c;程序可能…

微软最热门的10款前端开源项目!

本文来盘点微软开源的十大前端项目&#xff0c;这些项目在 Github 上获得了超过 45 万 Star&#xff01; Visual Studio Code Visual Studio Code 是一款由微软开发的开源的代码编辑器。它支持多种编程语言&#xff0c;如C、C、C#、Python、JavaScript 和 TypeScript 等&…

记一次linux下pip安装包时出错及奇怪的解决过程

一、问题说明 如图&#xff0c;在使用pip安装测速工具speedtest-cli时&#xff0c;终端提示“Externally managed environment &#xff08;从外部管理的环境&#xff09;”&#xff0c;导致无法安装该库。 二、问题解决 1 尝试提示的解决方案&#xff0c;改用命令apt inst…

c++获取当前时间的字符串

代码 void getNowTimePrefix(std::string& prefix) {std::time_t nowTime;struct tm* p new tm;std::time(&nowTime);localtime_s(p, &nowTime);int year p->tm_year 1900;int month p->tm_mon 1;int day p->tm_mday;int hour p->tm_hour;int …

机器学习算法基础--逻辑回归

目录 1.数据收集及处理 2.数据提取及可视化 3.逻辑回归训练样本并且测试 4.绘制散点决策边界 逻辑回归的方法已经在数学建模里面讲过了&#xff0c;这里就不多讲了。 本篇我们主要是利用逻辑回归的方法来求解分类问题。 1.数据获取及处理 import pandas as pd from sklearn…

计算机竞赛 深度学习YOLO抽烟行为检测 - python opencv

文章目录 1 前言1 课题背景2 实现效果3 Yolov5算法3.1 简介3.2 相关技术 4 数据集处理及实验5 部分核心代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习YOLO抽烟行为检测 该项目较为新颖&#xff0c;适合作为竞赛课…

《Kubernetes部署篇:Ubuntu20.04基于外部etcd+部署kubernetes1.25.14集群(多主多从)》

一、部署架构图 1、架构图如下所示: 2、部署流程图如下所示: 二、环境信息 1、资源下载基于外部etcd+部署容器版kubernetes1.25.14集群资源合集 2、部署规划主机名K8S版本系统版本内核版本IP地址备注k8s-master-121.25.14Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.12ma…

[Hadoop] start-dfs.sh ssh报错

Permission denied (publickey 决解方案 相关命令 cd ~/.sshssh-keygen -t rsa -p""cat id_rsa.pub >> authorized_keyschmod 0600 authorized_keys 相关链接Hadoop: start-dfs.sh permission denied - Stack Overflow Java HotSpot(TM) Server VM warning…

深度学习-一个简单的深度学习推导

文章目录 前言1.sigmod函数2.sigmoid求导3.损失函数loss4.神经网络1.神经网络结构2.公式表示-正向传播3.梯度计算1.Loss 函数2.梯度1.反向传播第2-3层2.反向传播第1-2层 3.python代码 前言 本章主要推导一个简单的两层神经网络。 其中公式入口【入口】 1.sigmod函数 激活函数…

idea创建springboot项+集成阿里连接池druid

创建项目并集成流程 1&#xff1a;前提准备2&#xff1a;创建springboot项目流程3&#xff1a;集成阿里连接池步骤4&#xff1a;集成swagger方便测试5&#xff1a;书写增删改查进行测试6&#xff1a;项目gitee地址 1&#xff1a;前提准备 准备开发工具&#xff1a;idea java环…

世界前沿技术发展报告2023《世界信息技术发展报告》(三)量子信息技术

&#xff08;三&#xff09;量子信息技术 1. 概述2. 量子计算2.1 阿里巴巴达摩院成功研制两比特量子芯片&#xff0c;单比特操控精度超99.97%2.2 加拿大Xanadu公司开发出可编程光量子计算机2.3 美国英伟达公司为经典-量子混合计算推出开发架构2.4 日本国家自然科学研究所开发出…