设计模式—观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。
在观察者模式中,有两个核心角色:
-
Subject(主题):也称为被观察者或可观察对象,它是具有状态的对象,当其状态发生变化时,会通知所有的观察者。
-
Observer(观察者):也称为订阅者或观察者,它定义了一个接口,用于接收主题的通知,并进行相应的处理。
观察者模式的工作原理如下:
-
主题维护一个观察者列表,用于存储所有订阅该主题的观察者。
-
当主题的状态发生变化时,会遍历观察者列表,依次调用每个观察者的更新方法。
-
观察者收到通知后,根据主题的状态进行相应的处理。
观察者模式的优点包括:
-
解耦性:主题和观察者之间是松耦合的,它们可以独立地进行扩展和修改,互不影响。
-
可扩展性:可以方便地增加新的观察者,以及在不修改主题代码的情况下增加新的主题。
-
易于维护:由于主题和观察者之间的关系是明确的,代码的维护和调试相对容易。
举个例子:被观察者=新闻,观察者有“播放新闻”和“打印新闻”,当有新的新闻产生时,立刻播放和打印新闻。(建议尽量面向抽象编程、接口编程)
先定义观察者和被观察者的抽象类。
/*** 观察者抽象*/
public abstract class Observer {/*** 处理新闻内容* @param msg*/public abstract void handle(String msg);/*** 观察者的身份* @return*/public abstract String identity();
}
/*** 被观察者抽象*/
public abstract class Subject {/*** 观察者列表*/public List<Observer> observerList;/*** 加入观察者* @param observer*/public abstract void register(Observer observer);/*** 剔除观察者* @param observer*/public abstract void cancel(Observer observer);/*** 通知内容* @param msg*/public abstract void notice(String msg);
}
再定义新闻类,继承了被观察者抽象类,表示自己是某个具有实际业务含义的被观察者。
public class News extends Subject {public News() {this.observerList = new ArrayList<>();}@Overridepublic void register(Observer observer) {this.observerList.add(observer);}@Overridepublic void cancel(Observer observer) {for (Observer ob : this.observerList) {if (ob.identity().equals(observer.identity())) {this.observerList.remove(ob);}}}@Overridepublic void notice(String msg) {for (Observer ob : this.observerList) {ob.handle(msg);}}
}
定义播放新闻类和打印新闻类,表示具体的观察者。
public class PlayNews extends Observer {Logger logger = LoggerFactory.getLogger(PlayNews.class);@Overridepublic void handle(String msg) {logger.info("播放新闻:{}", msg);}@Overridepublic String identity() {return "play";}
}public class PrintNews extends Observer {Logger logger = LoggerFactory.getLogger(PrintNews.class);@Overridepublic void handle(String msg) {logger.info("打印新闻:{}", msg);}@Overridepublic String identity() {return "print";}
}
测试一下:
public class Test {public static void main(String[] args) {News news = new News();PlayNews playNews = new PlayNews();PrintNews printNews = new PrintNews();news.register(playNews);news.register(printNews);news.notice("油价微涨1元");news.cancel(playNews);news.notice("油价暴跌1分");}
}

个人理解:
1、观察者模式类似于发布-订阅,需要被观察者发出信息让观察者去处理,但是又与发布-订阅模式不同,观察者与被观察者是直接联系,互相有感知,中间没有第三方角色存在,而发布-订阅模式中,发布者与订阅者之间有第三方角色存在,比如kafka中,生产者发送消息到 topic,消费者从topic获取消息,而不是生产者直接发消息给消费者,更多地是体现发布者与订阅者之间的相互无感知,解耦,以及异步机制。
2、观察者模式的亮点在于它的“加入观察者”、“剔除观察者”思想,适合那些观察者随时可变的场景,否则就没什么特点可言了,还不如策略模式。
相关文章:
设计模式—观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。 在观察者模式中,有两个核心角色…...
Java_EasyExcel_导入_导出Java-js
easyExcel导入 从easyexcel官网中拷贝过来,使用到的,这是使用监听器的方法。 EasyExcel.read(file.getInputStream(), BaseStoreDataExcelVo.class, new ReadListener<BaseStoreDataExcelVo>() {/*** 单次缓存的数据量*/public static final int…...
循环神经网络-RNN记忆能力实验 [HBU]
目录 一、循环神经网络 二、循环神经网络的记忆能力实验 三、数据集构建 数据集的构建函数 加载数据并进行数据划分 构造Dataset类 四、模型构建 嵌入层 SRN层 五、模型训练 训练指定长度的数字预测模型 多组训练 损失曲线展示 六、模型评价 参考《神经网络与深度…...
P1044 [NOIP2003 普及组] 栈——卡特兰数
传送门: P1044 [NOIP2003 普及组] 栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1044 公式一:递推式(注意开 long long ,然后 先乘完再除,防止下取整) typedef long long ll;…...
9:00面试,9:06就出来了,问的问题有点变态。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到12月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40…...
ets:tab2list的不足之处与替代方法,以及gen_server中使用ets的优缺点
ets:tab2list 是 Erlang/OTP 中的一个函数,用于将 ETS(Erlang Term Storage)表转换为列表。ETS 是 Erlang 中的一个内建数据库,允许开发者在内存中存储大量数据。 一、ets:tab2list 的不足之处: 性能问题:…...
软件测试之压力测试详解
一、什么是压力测试 软件测试中:压力测试(Stress Test),也称为强度测试、负载测试。压力测试是模拟实际应用的软硬件环境及用户使用过程的系统负荷,长时间或超大负荷地运行测试软件,来测试被测系统的性能、…...
SpringBoot之请求的详细解析
1. 请求 在本章节呢,我们主要讲解,如何接收页面传递过来的请求数据。 1.1 Postman 之前我们课程中有提到当前最为主流的开发模式:前后端分离 在这种模式下,前端技术人员基于"接口文档",开发前端程序&…...
mac 环境下 goframe安装GF开发工具 gf-cli(安装包方式安装)
mac 环境下 goframe安装GF开发工具 gf-cli(安装包方式安装) 安装包网址 链接: link 终端输入命令进行安装 ./gf_darwin_amd64 但是产生如下报错,无法安装 使用一下命令给安装权限 chmod 0777 gf_darwin_amd64 && ./gf_darwin_a…...
Navicat 技术指引 | 适用于 GaussDB 分布式的数据迁移工具
Navicat Premium(16.3.3 Windows 版或以上)正式支持 GaussDB 分布式数据库。GaussDB 分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能,还提供强大的高阶功能(如模型、结…...
【TiDB理论知识10】TiDB6.0新特性
新特性 Placement Rules in SQL 小表缓存 内存悲观锁 Top SQL TiDB Enterprise Manager 一 Placement Rules in SQL Placement Rules in SQL 之前会遇到的问题 比如 北京的业务需要访问 T2 和 T3表 ,但是T3表的数据在纽约 纽约的业务需要问访T4 T5 T6表…...
MySQL笔记-第15章_存储过程与函数
视频链接:【MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板】 文章目录 第15章_存储过程与函数1. 存储过程概述1.1 理解1.2 分类 2. 创建存储过程2.1 语法分析2.2 代码举例 3. 调用存储过程3.1 调用格式3.2 代码举…...
12月12日作业
设计一个闹钟 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QTime> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass …...
基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(二)
目录 前言引言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理1)数据介绍2)数据测试3)数据处理 相关其它博客工程源代码下载其它资料下载 前言 博主前段时间发布了一篇有关方言识别和分类模型训练的博客,在读者…...
secrets --- 生成管理密码的安全随机数
3.6 新版功能. 源代码: Lib/secrets.py secrets 模块用于生成高度加密的随机数,适于管理密码、账户验证、安全凭据及机密数据。 最好用 secrets 替代 random 模块的默认伪随机数生成器,该生成器适用于建模和模拟,不宜用于安全与加密。 参见…...
宇视科技视频监控 main-cgi 文件信息泄露漏洞
宇视科技视频监控 main-cgi 文件信息泄露漏洞 一、产品简介二、漏概述三、复现环境四、漏洞检测手工抓包自动化检测 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#…...
【数学建模】《实战数学建模:例题与讲解》第十一讲-因子分析、聚类与主成分(含Matlab代码)
【数学建模】《实战数学建模:例题与讲解》第十一讲-因子分析、聚类与主成分(含Matlab代码) 基本概念聚类分析Q型聚类分析R型聚类分析 主成分分析因子分析 习题10.11. 题目要求2.解题过程3.程序4.结果 习题10.21. 题目要求2.解题过程3.程序4.结…...
Python查找列表中不重复的数字
Python每日一练 文章目录 Python每日一练问题:函数输入函数输出 代码实现示例输入:示例输出: 总结 问题: 编写一个程序来查找列表中不重复的数字。 定义函数find_unique(),它接受一个列表作为参数。 在函数内部&…...
用docker创建jmeter容器,如何实现性能测试?
用 docker 创建 jmeter 容器, 实现性能测试 我们都知道,jmeter可以做接口测试,也可以用于性能测试,现在企业中性能测试也大多使用jmeter。docker是最近这些年流行起来的容器部署工具,可以创建一个容器,然后把项目放到…...
pytest-fixtured自动化测试详解
fixture的作用 1.同unittest的setup和teardown,作为测试前后的初始化设置。 fixture的使用 1.作为前置条件使用 2.fixture的的作用范围 1.作为前置条件使用 pytest.fixture() def a():return 3def test_b(a):assert a3 2.fixture的作用范围 首先实例化更高范围的fixture…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
