当前位置: 首页 > news >正文

【设计模式】观察者模式

什么是观察者模式?

观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。

观察者模式的角色:

Subject:抽象主题(被观察者),每一个主题可以有多个观察者,并将所有观察者对象的引用保存在一个集合里,被观察者提供一个接口,可以增加和删除观察者角色

ConcreteSubject:具体主题,将有关状态存入具体观察者对象,在主题发生改变时,给所有的观察者发出通知

Observer:抽象观察者,为所有的具体观察者定义一个更新接口,该接口的作用是在收到主题的通知时能够及时的更新自己

ConcreteObserver:具体观察者,实现抽象观察者角色定义的更新接口,以便使本身的状态与主题状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

参考来自设计模式(五)观察者模式,作者:刘望舒

观察者模式的使用场景:

观察者模式是一种对象行为型模式,它通常用于以下场景:

  • 消息服务器系统。
  • 社交媒体平台。
  • 邮件系统。
  • 图形界面应用程序。
  • 游戏。
  • 实现团队协作,提高工作效率。
  • 观察者模式可以在不同对象之间创建有效关系,从而更有效地开发高质量软件。

具体实现:

假设有这么一个场景:我是B站up主,有很多粉丝关注我,我发视频了,他们就会点赞我,我发癫了(说些不好的话)他们就会取关我。
在这种场景下,就很使用观察者模式,粉丝们关注我,根据我的状态而动态地做出反应。

观察者的接口

public interface MyObserver {void execute(String upName);
}

观察者对象

public class fans implements MyObserver {private String name;public fans(String name){this.name = name;}// 根据msg动态地执行方法@Overridepublic void execute(String msg) {if("更新了".equals(msg)){System.out.println(this.name+"点赞了你");}if("发癫了".equals(msg)){System.out.println(this.name+"举报了你");}}
}

被观察者接口

public interface SupObject {// 将粉丝增加在通知列表void add(MyObserver myObserver);// 将粉丝删除出通知列表void delete(MyObserver myObserver);// 通知void notify(String upName);
}

被观察者对象

public class up implements SupObject{List<MyObserver> notifyList = new ArrayList<>();@Overridepublic void add(MyObserver myObserver) {notifyList.add(myObserver);}@Overridepublic void delete(MyObserver myObserver) {notifyList.remove(myObserver);}@Overridepublic void notify(String msg) {notifyList.forEach(t-> t.execute(msg));}
}

执行器

public class client {public static void main(String[] args) {fans fans1 = new fans("小约翰可汗");fans fans2 = new fans("CSGO玩机器");fans fans3 = new fans("徐云流浪中国");up up = new up();up.add(fans1);up.add(fans2);up.add(fans3);up.notify("更新了");}
}

效果:

在这里插入图片描述

观察者模式的优缺点:

优点

解除耦合,让耦合的双方都依赖于抽象,从而使得各自的变换都不会影响另一边的变换。

缺点

在应用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。

观察者模式和发布订阅模式的不同:

通过上面的代码,可能回产生这样的疑问?
这不是“被观察者”主动发送消息给“观察者”的吗?这么叫做观察者模式呢?主被动关系是不是搞反了?
其实观察者模式也叫做发布订阅模式。
比如《heah in first》中,就曾这么写

Publishers + Subscribers = Observer Pattern
在这里插入图片描述

但是!他们还是有差别的
在发布订阅模式里,发布者,并不会直接通知订阅者,换句话说,发布者和订阅者,彼此互不相识。
但在观察者模式中,观察者与被观察者是直接通信的。
这就是他们的差别:
观察者模式主打一个松耦合,但是他们还是耦合的。
但是发布订阅模式,完完全全的松开了!

相关文章:

【设计模式】观察者模式

什么是观察者模式&#xff1f; 观察者模式&#xff08;又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;属于行为型模式的一种&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态…...

ORCA优化器浅析——CDXLOperator Base class for operators in a DXL tree

如上图所示&#xff0c;CDXLOperator作为Base class for operators in a DXL tree&#xff0c;其子类CDXLLogical、CDXLScalar、CDXLPhysical作为逻辑节点、物理节点和Scalar节点的DXL表示类&#xff0c;因此其包含了这些类的共同部分特性&#xff0c;比如获取其DXL节点表示的函…...

go入门实践四-go实现一个简单的tcp-socks5代理服务

文章目录 前言socks协议简介go实现一个简单的socks5代理运行与压测抓包验证 前言 SOCKS是一种网络传输协议&#xff0c;主要用于客户端与外网服务器之间通讯的中间传递。协议在应用层和传输层之间。 本文使用先了解socks协议。然后实现一个socks5的tcp代理服务端。最后&#…...

div 中元素居中的N种常用方法

本文主要记录几种常用的div盒子水平垂直都居中的方法。本文主要参考了该篇博文并实践加以记录说明以加深理解记忆 css之div盒子居中常用方法大全 本文例子使用的 html body结构下的div 盒子模型如下&#xff1a; <body><div class"container"><div c…...

Java获取指定文件夹下目录下所有视频并复制到另一个地方

import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption;public class VideoCopier {public static void main(String[] args) {// 指定源文件夹路径和目标文件夹路径String sourceFolderPath "path/to…...

windows server 2016 搭建使用 svn 服务器教程

参考教程&#xff1a; https://zhuanlan.zhihu.com/p/428552058 https://blog.csdn.net/weixin_33897722/article/details/85602029 配置环境 windows server 2016 远程服务器公网 ip 安装 SVN 服务端 下载 svn 服务端安装包&#xff1a;https://www.visualsvn.com/download…...

【Python】如何判断时间序列数据是否为平稳时间序列或非平稳时间序列?

判断时间序列数据是否为平稳时间序列或非平稳时间序列&#xff0c;通常可以通过以下方法&#xff1a; &#xff08;1&#xff09;观察时间序列数据的均值和方差是否随时间变化而发生明显的改变。若均值和方差变化明显&#xff0c;则该时间序列数据可能为非平稳时间序列&#x…...

Labview控制APx(Audio Precision)进行测试测量(六)

用 LabVIEW 驱动 VIs生成任意波形 在 APx500 应用程序中&#xff0c;默认波形类型为正弦。这是指 APx 内置的正弦发生器&#xff0c;根据信号路径设置&#xff0c;许多测量还允许其他内置波形&#xff0c;如方波&#xff0c;分裂正弦波或分裂相位&#xff0c;以及使用导入的。w…...

【Linux】网络协议总结

目录 网络协议总结 应用层 传输层 网络层 数据链路层 网络协议总结 应用层 应用层的作用&#xff1a;负责应用程序间沟通&#xff0c;完成一系列业务处理所需服务。能够根据自己的需求&#xff0c;设计对应的应用层协议。了解HTTP协议。理解DNS的原理和工作流程。 传…...

如何轻松注册企业邮箱?快速掌握超简单的注册技巧!

随着互联网的发展&#xff0c;越来越多的企业开始使用电子邮件作为通信工具。企业邮箱不仅可以提高企业的工作效率&#xff0c;还可以使企业通信更加便捷、保密性更高。那么&#xff0c;企业邮箱怎么注册申请呢&#xff1f;下面我们来详细介绍一下。 第一步&#xff1a;选择邮箱…...

【行为型设计模式】C#设计模式之观察者模式

题目&#xff1a;假设你正在开发一个简单的新闻发布系统&#xff0c;该系统允许用户订阅不同的新闻频道&#xff0c;并在有新闻发布时向订阅者发送通知。使用观察者模式设计和实现该系统。观察者模式的相关概念和定义&#xff1a; 观察者模式是一种行为设计模式&#xff0c;它定…...

《Java面向对象程序设计》学习笔记——第 8 章 设计模式

​专栏&#xff1a;《Java面向对象程序设计》学习笔记 第 8 章 设计模式 一个好的设计系统往往是易维护、易扩展、易复用的。 8.1 设计模式简介 8.1.1 什么是设计模式 一个设计模式 (pattern) 是针对某一类问题的最佳解决方案&#xff0c;而且己经被成功应用于许多系统的设…...

Java学习笔记28——字节流1

IO流概述和分类 IO流IO流的分类字节流字节流写数据FileOutputStream字节流写数据的三种方式字节流写数据的两个问题字节流写数据加异常处理 IO流 IO&#xff1a;输入输出 流&#xff1a;一种抽象的概念&#xff0c;是对数据传输的总称&#xff0c;流的本质就是数据传输 IO流的…...

C++连接串口方式(MFC版本)(简单版本)

ComSerialPort.h /*_________________________串口________________________________*/class Com_SerialPort { public:Com_SerialPort();Com_SerialPort(int port, int baudRate, int byteSize, int parity, int stopBits);~Com_SerialPort(); public:bool Connect(bool bMut…...

ospf重发布

华子目录 一、实验拓扑二、实验要求三、实验思路1、配置接口IP地址以及环回地址&#xff08;以此类推&#xff09;2、配置动态路由协议3、重发布4、更改接口类型5、配置路由策略 一、实验拓扑 二、实验要求 1、使用双点双向重发布2、所有路由器进行最佳选路3、存在备份路径&am…...

基于weka手工实现K-means

一、K-means聚类算法 K均值聚类&#xff08;K-means clustering&#xff09;是一种常见的无监督学习算法&#xff0c;用于将数据集中的样本划分为K个不同的类别或簇。它通过最小化样本点与所属簇中心点之间的距离来确定最佳的簇划分。 K均值聚类的基本思想如下&#xff1a; …...

分布式系统监控zabbix安装部署及使用

分布式系统监控zabbix安装部署及使用 一.zabbix监控 1.什么是zabbix zabbix&#xff1a;是一款开源免费的&#xff0c;自动化发现服务与网络设备的分布式监控&#xff0c;可以监视应用层服务并以web前端页面集中管理并展示。 2.zabbix功能 监控服务器cpu负载、服务器内存使…...

【H5】使用 JavaScript 和 CSS 来完成实现鼠标接触时显示一个图片弹窗

以下是一个示例&#xff0c;演示了如何在鼠标接触时显示一个图片弹窗&#xff1a; HTML: <a href"#" class"popup-link" target"_blank"><i class"fab fa-weixin"></i> </a><div id"popup-containe…...

CSS选择器分类梳理并高亮重点

前言 主要内容来自菜鸟教程 CSS 选择器 | 菜鸟教程 分类是我自己理解的分类&#xff0c;示例说明优化统一了表述风格。 正文 选择器CSS示例示例说明基础*2*选择所有元素:root3:root选择文档的根元素element1p选择所有<p>元素:not(selector)3:not(p)选择所有并非p元素…...

Python批量给excel文件加密

有时候我们需要定期给公司外部发邮件&#xff0c;在自动化发邮件的时候需要对文件进行加密传输。本文和你一起来探索用python给单个文件和批量文件加密。    python自动化发邮件可参考【干货】用Python每天定时发送监控邮件。 文章目录 一、安装pypiwin32包二、定义给excel加…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...