[学习记录] 设计模式 3. 观察者模式

观察者模式

参考:

  • bugstack 虫洞栈
  • Refactoring
  • https://www.cnblogs.com/myseries/p/8735490.html
  • https://www.jianshu.com/p/4f1cd513a72d

当一个行为发生时传递信息给另外一个用户接收做出相应的处理,两者之间没有直接的耦合关联。

在我们编程开发中也会常用到一些观察者的模式或者组件,例如我们经常使用的MQ服务,虽然MQ服务是有一个通知中心并不是每一个类服务进行通知,但整体上也可以算作是观察者模式的思路设计。再比如可能有做过的一些类似事件监听总线,让主线服务与其他辅线业务服务分离,为了使系统降低耦合和增强扩展性,也会使用观察者模式进行处理。

1. 结构

在这里插入图片描述

2. 实现

2.1 Obverse 和 Obversable

该方式已经在 Java 9 被弃用

This class and the Observer interface have been deprecated. The event model supported by Observer and Observable is quite limited, the order of notifications delivered by Observable is unspecified, and state changes are not in one-for-one correspondence with notifications. For a richer event model, consider using the java.beans package. For reliable and ordered messaging among threads, consider using one of the concurrent data structures in the java.util.concurrent package. For reactive streams style programming, see the java.util.concurrent.Flow API.

2.1.1 被观察者

当被观察者的 state 变化时,通知所有进制的观察者。

public class Subject extends Observable {private int state;public int getState() {return state;}public void setState(int state) {this.state = state;this.setChanged();this.notifyObservers();}
}
2.1.2 多个观察者
public class BinaryObserver implements Observer {public BinaryObserver(Observable observable) {observable.addObserver(this);}@Overridepublic void update(Observable o, Object arg) {if (o instanceof Subject) {System.out.println("Binary String: " + Integer.toBinaryString(((Subject) o).getState()));}}
}
public class OctalObserver implements Observer {public OctalObserver(Observable observable) {observable.addObserver(this);}@Overridepublic void update(Observable o, Object arg) {if (o instanceof Subject) {System.out.println("Binary String: " + Integer.toOctalString(((Subject) o).getState()));}}
}
public class HexaObserver implements Observer {public HexaObserver(Observable observable) {observable.addObserver(this);}@Overridepublic void update(Observable o, Object arg) {if (o instanceof Subject) {System.out.println("Binary String: " + Integer.toHexString(((Subject) o).getState()));}}
}
2.1.3 测试
public class Test{public static void main(String[] args) {Subject subject = new Subject();new BinaryObserver(subject);new OctalObserver(subject);new HexaObserver(subject);System.out.println("First state change: 15");subject.setState(15);System.out.println("Second state change: 10");subject.setState(10);}
}

还值得优化的部分:可以把添加观察者还有删除观察者的功能提取到一个单独的管理类中。

2.2 PropertyChangeEvent,PropertyChangeSupport,PropertyChangeListener

这三个类分别对应的职责:

  • PropertyChangeListener:观察者
  • PropertyChangeSupport:管理者
  • PropertyChangeEvent:事件
class EventSource {private String name;/** 在事件源的地方添加一个PropertyChangeSupport对象,间接地由它负责添加监听、激发事件*/private final PropertyChangeSupport listeners = new PropertyChangeSupport(this);/*** 在事件源上添加监听,实际上是在PropertyChangeSupport对象上添加监听*/public void addListener(PropertyChangeListener listener) {listeners.addPropertyChangeListener(listener);}/*** 同上*/public void removeListener(PropertyChangeListener listener) {listeners.removePropertyChangeListener(listener);}/*** 事件源发生变化时,也是通过PropertyChangeSupport对象把事件发送到监听者上的*/public void setName(String name) {String oldValue = this.name;this.name = name;// 触发事件源,监听者得到触发变化listeners.firePropertyChange("name", oldValue, this.name);}
}@Slf4j
class Monitor implements PropertyChangeListener {@Overridepublic void propertyChange(PropertyChangeEvent evt) {log.info("事件源 {} 发生变化, {} ==> {}", evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());}
}public class TestPropertyChangeSupport {public static void main(String[] args) {EventSource eventSource = new EventSource();Monitor monitor = new Monitor();//在事件源上添加监听,发生变化时就会调用propertyChange方法eventSource.addListener(monitor);eventSource.setName("11");}
}

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

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

相关文章

Hutool工具包:http客户端工具(使用教程)

目录 一、Hutool介绍 二、笔者的话 三、引入依赖 四、大致步骤 五、GET请求 5.1 代码 5.2 结果展示 六、POST请求 6.1 代码一(Form Data类型参数) 6.2 结果展示 6.3 代码二(Form Data类型参数 - 含上传文件) 6.4 结果…

开发高性能知识付费平台:关键技术策略

引言 在构建知识付费平台时,高性能是确保用户满意度和平台成功的关键因素之一。本文将探讨一些关键的技术策略,帮助开发者打造高性能的知识付费平台。 1. 前端性能优化 使用CDN加速资源加载 使用内容分发网络(CDN)来托管和加…

JavaWeb后端开发 JWT令牌解析 登录校验 通用模板/SpringBoot整合

目录 实现思路 会话跟踪的三个方案--引出Jwt令牌技术 1.访问cookie的值,在同一会话的不同请求之间共享数据 2.session 3.现代普遍采用的令牌技术--JWT令牌 JWT令牌技术 ​第一步--生成令牌 1.引入依赖 2.生成令牌 第二步--校验令牌 第三步--登录下发令牌 需要解决的…

黑马JVM总结(二十三)

(1)字节码指令-init 方法体内有一些字节,对应着将来要由java虚拟机执行方法内的代码,构造方法里5个字节代码,main方法里有9个字节的代码 java虚拟机呢内部有一个解释器,这个解释器呢可以识别平台无关的字…

四种自动化测试模型实例及优缺点

【软件测试面试突击班】如何逼自己一周刷完软件测试八股文教程,刷完面试就稳了,你也可以当高薪软件测试工程师(自动化测试) 一,线性测试 1.概念: 通过录制或编写对应应用程序的操作步骤产生的线性脚本。单…

分工是财富的秘密

友情提示:这是一篇干货,需要深度阅读 前几天,我看到一个做自媒体的大 V 说了这么一个观点:分工是财富的秘密。 然后,我根据这句话,自己做了点引申。 分工是财富的秘密。分工越细,赚钱机会越多&a…

OpenGL之坐标系统

将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分步进行的,也就是类似于流水线那样子。在流水线中,物体的顶点在最终转化为屏幕坐标之前还会被变换到多个坐标系统(Coordinate System)。将物体的坐标变换到几个过渡坐标系(Inte…

从Python代码到诗

🐳序言 在Python社区,没有强制的编码标准,这虽然赋予了开发者更多的自由,但也导致代码风格不一致性。使得部分代码变得晦涩难懂,本文将探讨一系列的开发技巧和最佳实践,开发出优雅的Python脚本。 1、参数接…

ElasticSearch(三)

1.数据聚合 聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些…

laravel框架 - 消息队列如何使用

业务场景:项目里边有很多视频资源需要上传到抖音资源库,通过队列一条一条上传。 参考实例:发送邮件,仅供参考 (1)创建任务【生成任务类】 在你的应用程序中,队列的任务类都默认放在 app/Jobs 目录下。如果这个目录不存…

解决ubuntu系统python2.7安装uwsgi报错

背景 因为项目老旧,仍需使用python2.7,仍需要使用pip2 安装依赖。在安装uwsgi的时候,报错。 错误一 Building wheel for uwsgi (setup.py) ... error ERROR: Command errored out with exit status 1: command: /usr/bin/python2 -u -…

vulhub打靶第三周

第三周 靶机下载地址:https://www.vulnhub.com/entry/chronos-1,735/ 环境折磨导致做晚了,再加上期末的考试多耽搁下来了,然后就是辗转反侧打比赛,拖了这么久,时隔三个月重新开打 因为陆陆续续打了两次,所…

[winerror 5] 拒绝访问。: ‘..\\data‘解决方案

使用Jupyter Notebook学习深度学习时出现错误如下:[winerror 5] 拒绝访问。: ‘…\data’ 解决方法: 打开anaconda3找到对应环境的python.exe 点开属性,点安全,选择如下: 点编辑,选择User,勾…

9、DVWA——XSS(Stored)

文章目录 一、存储型XSS概述二、low2.1 源码分析2.2 通关分析 三、medium3.1 源码分析3.2 通关思路 四、high4.1 源码分析4.2 通关思路 一、存储型XSS概述 XSS,全称Cross Site Scripting,即跨站脚本攻击,某种意义上也是一种注入攻击&#xff…

李航老师《统计学习方法》第1章阅读笔记

1.1 统计学习 统计学习的特点 统计学习:计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析 现在人们提及机器学习时,往往指统计机器学习,所以可以认为本书介绍的是机器学习方法 统计学习的对象 统计学习研究的对象是数据(data)…

《Web安全基础》09. WAF 绕过

web 1:基本概念1.1:DoS & DDos1.2:CC 攻击1.3:扫描绕过方式 2:WAF 绕过2.1:信息收集阶段2.2:漏洞发现阶段2.3:权限控制阶段2.3.1:密码混淆2.3.2:变量覆盖…

解决方案:TSINGSEE青犀+智能分析网关助力智慧仓储智能化监管

为全面保障物流仓储的安全性与完整性,解决仓库管理难题,优化物流仓储方式,提升仓储效率,降低人工成本,旭帆科技推出智慧仓储AI视频智能分析方案,利用物联网、大数据、云计算等技术,对仓储管理进…

IDEA2023新UI回退老UI

idea2023年发布了新UI,如下所示 但是用起来真心不好用,各种位置也是错乱,用下面方法可以回退老UI

【轨道机器人】成功驱动伺服电机(学生电源、DCH调试软件、DH系列伺服驱动器)

1、硬件平台 工控机 学生电源 DH系列伺服驱动器 电机 调试平台:DCH 2、如何利用dch驱动电机 点击可驱动电机 下面的步骤是比较关键的几步: 3、遇到的问题 不能成功驱动电机,还和厂家那边打电话,询问 发现是这…

JavaScript简介引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 JavaScript简介&引入方式 简介&#xf…