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

news/2024/5/17 12:42:32

原理

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

被依赖的对象被观察者(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.mrgr.cn/p/27078216

相关文章

策略模式类图与代码

某大型购物中心欲开发一套收银软件&#xff0c;要求其能够支持购物中心在不同时期推出的各种促销活动&#xff0c;如打折、返利(例如&#xff0c;满300返100),等等。现采用策略(Strategy)模式实现该要求&#xff0c;得到如图7.13 所示的类图。 【Java 代码】 import java.util…

NPU硬件架构及张量技术开发

NPU硬件架构及张量技术开发 NPU 系统介绍 V853 芯片内置一颗 NPU,其处理性能为最大 1 TOPS 并有 128KB 内部高速缓存用于高速数据交换,支持 OpenCL、OpenVX、android NN 与 ONNX 的 API 调用,同时也支持导入大量常用的深度学习模型。 NPU 系统架构 NPU 的系统架构如下图所示…

阶段性学习汇报 4月19日

一、毕业设计和毕业论文 毕业设计后端功能基本实现&#xff0c;但是还有些具体的细节需要优化&#xff0c;例如这些图片的显示问题&#xff0c;前端只有个前端页面以及部分交互逻辑&#xff0c;还需进一步完善。我想在疾病预测这里加一个创新点&#xff0c;基于推荐算法。小程序…

(五)PostgreSQL的管理工具pgAdmin

PostgreSQL的管理工具pgAdmin pgAdmin 是一款流行的开源图形界面管理工具&#xff0c;用于 PostgreSQL 数据库的管理和开发。它提供了一个易于使用的界面&#xff0c;允许用户执行各种数据库任务&#xff0c;如创建和修改数据库对象&#xff08;表、视图、索引等&#xff09;、…

算法:位运算

算法&#xff1a;位运算 常见位运算操作基本题型模拟加法数字查找总结 常见位运算操作 在C/C中&#xff0c;有比较丰富的位运算操作符&#xff0c;常见的有&#xff1a; &&#xff1a;按位与 |&#xff1a;按位或 ~&#xff1a;按位取反 ^&#xff1a;按位异或 <<&a…

Win11 WSL2 install Ubuntu20.04 and Seismic Unix

Win11系统&#xff0c;先启用或关闭Windows功能&#xff0c;勾选“适用于Linux的Windows子系统”和“虚拟机平台”两项 设置wsl默认版本为wsl2&#xff0c;并更新 wsl --list --verbose # 查看安装版本及内容 wsl --set-default-version 2 # 设置wsl默认版本为wsl2 # 已安装…

nginx安装在linux上

nginx主要用于反向代理和负载均衡&#xff0c;现在简单的说说如何在linux操作系统上安装nginx 第一步&#xff1a;安装依赖 yum install -y gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel 第二步&#xff1a; 下载nginx&#xff0c;访问官网&#xff0c;ngin…

CentOS 7安装Zookeeper

说明&#xff1a;本文介绍如何在CentOS 7操作系统下使用Zookeeper 下载安装 首先&#xff0c;去官网下载所需要安装的版本&#xff0c;我这里下载3.4.9版本&#xff1b; 上传到云服务器上&#xff0c;解压 tar -xvf zookeeper-3.4.9.tar.gz修改配置 进入Zookeeper目录下的co…

jenkins 启动linux节点时 控制台中文显示问号乱码

新增一个jenkins节点时&#xff0c;遇到了控制台中文输出问号的问题。 网上各种配置jenkins的全局变量&#xff0c;都不行。 最终是 节点列表 ->对应节点 -> 启动方式 -> 高级 添加JVM选项 -Dfile.encodingUTF-8

C语言 递归

递归指的是在函数的定义中使用函数自身的方法。 举个例子&#xff1a; 从前有座山&#xff0c;山里有座庙&#xff0c;庙里有个老和尚&#xff0c;正在给小和尚讲故事呢&#xff01;故事是什么呢&#xff1f;“从前有座山&#xff0c;山里有座庙&#xff0c;庙里有个老和尚&…

用python实现四则运算的生成与判定

小组成员:2252316,2252326点击查看代码 import randomdef generate_question():operators= [+, -, *, /]while 1:operator1 = random.choice(operators)operator2 = random.choice(operators)num1 = random.randint(1, 100)num2 = random.randint(1, 100)num3 = random.randi…

自己的事情自己做:使用 Python Turtle 绘制 Python Logo

以下代码中&#xff0c;将向你展示一个有趣的程序&#xff0c;如何使用 Python Turtle 中绘制 Python Logo。Python 翻译成汉语是蟒蛇的意思&#xff0c;Python 的 Logo 也是两条缠绕在一起的蟒蛇。 import turtlepen turtle.Turtle() turtle.bgcolor("black") pe…

2024年五一杯数学建模B题思路分析

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

Ubuntu22.04 + ROS2 Humble的环境配置

Ubuntu22.04 ROS2 Humble的环境配置 文章目录 Ubuntu22.04 ROS2 Humble的环境配置(1) Set locale(2) Setup Sources(3)安装ROS2(4)检查是否成功安装 参考官方网站ROS2-Installation ROS2的各种版本及维护计划&#xff0c;可以参考ROS2-List of Distributions (1) Set locale…

Flattened Butterfly 扁平蝶形拓扑

Flattened Butterfly 扁平蝶形拓扑 1. 传统蝶形网络 Butterfly Topology2. 扁平蝶形拓扑 Flattened Butterfly3.On-Chip Flattened Butterfly 扁平蝶形拓扑应用于片上网络 Flattened Butterfly 扁平蝶形拓扑 扁平蝶形拓扑是一种经济高效的拓扑&#xff0c;适用于高基数路由器…

音乐盒组件Aplayer+Metingjs

Aplayer🍭 Wow, such a beautiful HTML5 music player(哇,好漂亮的HTML5音乐播放器) Aplayer是一个功能强大的HTML5音乐播放器 Aplayer官网文档:https://aplayer.js.org/#/MetingjsMetingjs基于Aplayer插件封装好的插件,开箱即用 Metingjs官网文档:https://github.com/me…

FebHost:谁可以注册.CA加拿大域名?

在加拿大&#xff0c;互联网域名的注册管理遵循一套独特的规则。特别是对于代表加拿大身份的顶级域名“.ca”&#xff0c;其申请和注册过程涉及一些严格的条件。这些条件确保了只有符合特定标准的个人或实体才能获得这一具有国家象征意义的网络地址。 首先&#xff0c;想要注册…

【算法练习】29:插入排序学习笔记

一、插入排序的算法思想 原理&#xff1a;将一个无序的数据序列逐步转化为有序序列。算法将待排序的数组分为两个部分已排序部分和未排序部分。 时间复杂度&#xff1a;插入排序的时间复杂度在最坏、平均和最好情况下的表现相同&#xff0c;均为 &#xff0c;其中 n 是待排序数…

flutter+Springboot的结合

我们团队的开发 前端采用flutter 后端采用spring boot 首先 完成了app的图标名字的修改 在app/src/main/res/mipmap 目录中 存放app图标 图片 在AndroidManifest.xml 文件中 修改对应的 名字 和图标 打开后是 我们的主页面 首先进来的是 主页面 但是各种功能无法使用 必须登录后…

在Windows安装R语言

直接安装R语言软件 下载网址&#xff1a;R: The R Project for Statistical Computing 下载点击install R for the first time 通过Anaconda下载RStudio 提前下载好Anaconda 点击Anaconda Navigate 点击RStudio的Install下载就好了