【设计模式】聊聊观察者设计模式原理及应用

原理

观察者模式属于行为模式,行为模式主要解决类和对象之间交互问题。
含义:在对象之间定义一个一对多的依赖,当一个对象状态改变时,所有依赖的对象会自动通知。

被依赖的对象被观察者(Observable) ,依赖的对象观察者(Observer),当然也可以叫发布-订阅等。
在这里插入图片描述

一个case

比如我们维护的用户中心,当用户进行注册的时候,就进行通知发送短信、WA、邮件等。

1.第一步,先定义被观察者接口,主要就是注册、删除、已经通知观察者。

/*** @author qxlx* @date 2024/4/13 22:25*/
public interface Subject {/*** 注册* @param observer*/void registerObserver(Observer observer);/*** 删除* @param observer*/void deleteObserver(Observer observer);/*** 发送事件* @param message*/void notifyObservers(String message);
}

2.定义贯彻者具体的行为

public interface Observer {void notify(String message);}

3.被观察者的具体实现,可以发送通过接口注册或删除观察者,当被观察者执行用户注册的方法时,就会触发通知观察者进行处理。
这里需要明确下,可以采用同步的方式 或者异步方式。因为对于注册接口来说响应时间还是比较重要的,采用线程的方式 可以提高接口性能。

/*** @author qxlx* @date 2024/4/13 22:27*/
public class ConcreteSubject implements Subject {private List<Observer> observerList = new CopyOnWriteArrayList<>();@Overridepublic void registerObserver(Observer observer) {observerList.add(observer);}@Overridepublic void deleteObserver(Observer observer) {observerList.remove(observer);}@Overridepublic void notifyObservers(String message) {// 1.同步调用// 2.异步非阻塞observerList.forEach(o -> o.notify(message));// new Thread()new Thread(() -> {observerList.forEach(o -> o.notify(message));}).start();// 线程池ThreadPoolUtil.getThreadPool(10).execute(() -> observerList.forEach(o -> o.notify(message)));}
}

4.定义具体的观察者实现类,发送邮件 或者发送wa

public class UserSendEmailObserver implements Observer{@Overridepublic void notify(String message) {System.out.println("用户注册成功,发送邮件通知!");}}public class UserWaSendObserver implements Observer{@Overridepublic void notify(String message) {System.out.println("用户注册成功,发送了wa通知");}
}

最终的Demo 其实就是这样,将观察者添加到被观察者上,观察者一旦执行了用户注册,就会触发对应动作,比如说新增新的动作,那么就可以直接添加一个发优惠卷的观察者。可以很好的进行拓展。

    public static void main(String[] args) {UserSendEmailObserver userSendEmailObserver = new UserSendEmailObserver();UserWaSendObserver userWaSendObserver = new UserWaSendObserver();ConcreteSubject concreteSubject = new ConcreteSubject();concreteSubject.registerObserver(userSendEmailObserver);concreteSubject.registerObserver(userWaSendObserver);concreteSubject.notifyObservers("register");}

在这里插入图片描述

Spring 中如何应用观察者模式

在spring源码中,IOC容器进行初始化的过程中,refresh() 方法中就包含观察者模式。而Spring进行了抽象,也就是将观察者和被观察者 进行调整成多播器和监听器,通过事件来驱动监听器的执行。
在这里插入图片描述
在这里插入图片描述

可以看到,整体的流程就是,初始化多播器对象,SimpleApplicationEventMulticaster,将监听器添加到多播器中。然后发布事件,调用监听器进行处理。可以发现其实设计模式在实际的应用中,思想相同的,但是落地的时候都有自己的调整。本质上还是当多个对象所依赖的对象有对应的事件时,需要做对应的动作。解耦合观察者和被观察者。

	//初始化事件多播功能(事件派发) Initialize event multicaster for this context.//初始化多播器 SimpleApplicationEventMulticaster 注册到IOC容器中initApplicationEventMulticaster();//注册监听器,从容器中获取所有的ApplicationListener;// Check for listener beans and register them.registerListeners();//发布事件 Last step: publish corresponding event.finishRefresh();

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

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

相关文章

MCU最小系统的电源模块设计和复位模块的设计

最小操作系统就是一个电路&#xff0c;这个电路里面必须要的东西&#xff08;如人需要喝水吃饭温度等情况&#xff0c;才能或者&#xff09; 现在我们要解决这三个问题 这里V开头的&#xff0c;都是电源管脚 这里解释一下&#xff1a; 这里要注意哪些是电路电压&#xff0c;哪…

API接口京东开放平台item_get-获得京东商品详情API接口根据商品ID查询商品标题价格描述等详情数据

京东商品详情API接口可以提供以下方面的信息&#xff1a; 商品基础信息&#xff1a;包括商品的标题、价格、描述、图片等基本信息&#xff0c;这是构建电商平台的基础数据。商品分类信息&#xff1a;帮助用户更好地了解商品所属的类别&#xff0c;便于商品筛选和查找。商品销售…

YOLOv5目标检测优化点(添加小目标头检测)

文章目录 1、前言2、如何计算参数3、YOLOv5小目标改进-13.1、结构文件3.2、结构图3.3、参数对比3.3.1、yolov5l.yaml 解析表3.3.2、 yolov5l-4P.yaml 解析表 4、YOLOv5小目标改进-24.1、结构文件4.2、结构图 5、YOLOv5小目标改进-35.1、结构文件 6、YOLOv5小目标改进-46.1、结构…

云服务器安装Mysql、MariaDB、Redis、tomcat

前置工作 进入根目录 cd / 进入/user/local文件夹 上传压缩包 rz 压缩包 Mysql 1.下载并安装MySQL官方的 Yum Repository wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-…

[Android]申请成为Google Play个人开发者

1.注册Google邮箱 2.进入play.google.com选择成为“企业”或是“个人”开发者 https://play.google.com/console 3.选择成为个人开发者 这里会提示你申请的所需条件。有告诉我们&#xff0c;后面需要支付$25。 继续的话&#xff0c;要求填写一个开发者名称。 4.创建付款信息…

cannot import name ‘get_host‘ from ‘urllib3.util.url‘

Error in py_module_import(module, convert convert) : ImportError: cannot import name get_host from urllib3.util.url (D:\\url.py) Run reticulate::py_last_error() for details. 这个错误表明在 urllib3 模块的 util.url 子模块中找不到名为 get_host 的函数。这可能…

康耐视visionpro-CogFindCircleTool操作工具详细说明

◆CogFindCircleTool]功能说明: 通过用多个卡尺找到多个点来拟合所要找的圆 ◆CogFindCircleTool操作说明: ①.打开工具栏,双击或点击鼠标拖拽添加CogFindCircleTool工具 ②.添加输入图像,右键“链接到”或以连线拖拽的方式选择相应输入源 ③预期的圆弧:设置预期圆弧的…

Linux gcc 6

本章开始学习工具 什么是工具&#xff1f; 本质也是指令 yum 命令 小火车 sudo yum install sl&#xff08;安装sl&#xff09; sudo yum install -y sl //直接yes就不提示了 yum list //将yum源上的软件都穷举出来 yum search sl //结果不友好&#xff0c;不推荐 yum lis…

Tomcat源码解析——Tomcat的启动流程

一、启动脚本 当我们在服务启动Tomcat时&#xff0c;都是通过执行startup.sh脚本启动。 在Tomcat的启动脚本startup.sh中&#xff0c;最终会去执行catalina.sh脚本&#xff0c;传递的参数是start。 在catalina.sh脚本中&#xff0c;前面是环境判断和初始化参数&#xff0c;最终…

.cur 鼠标光标编辑器

详解透明贴图和三元光栅操作 - CodeBus 鼠标指针文件格式解析——Windows&#xff08;二&#xff09; (qq.com) [C/C] RGBA数组生成Windows下的ico文件_c ico格式-CSDN博客 色环设计 - CodeBus 左键绘制 右键选颜色 ctrl右键设置鼠标热点 F1导出.cur文件 //代码来源&…

Linux的重要命令(二)+了解Linux目录结构

目录 一.Linux的目录结构 二.查看文件内容命令 1.cat 命令 2.more 命令 3.less 命令 4.head 命令 5.tail 命令 6.拓展 head 和 tail 的其他用法 ​编辑 三.统计文件内容的命令-wc ​编辑 四.检索和过滤文件内容的命令-grep ​编辑 ​编辑 五.压缩命令 gzip 和 bz…

基于R语言实现的负二项回归模型【理解与实现】-理解负二项回归模型和泊松回归模型之间的区别

前言 我们可以在R语言中使用MASS包中的glm.nb函数来拟合负二项模型&#xff0c;以及使用glm函数来拟合泊松模型。以下是一个详细的过程&#xff0c;包括模拟数据的生成、模型的拟合、结果的比较和解释。 需要的包 if (!require("MASS")) install.packages("M…