观察者模式-对象间的联动
有个商城小程序,用户希望当有新品上市的时候能通知他们。这样用户就可以不要时刻盯着小程序了。在这个场景中,用户向小程序订阅了一个服务——发送新品短信。小程序在有新品上线时负责向订阅客户发出这个消息。
这就是发布-订阅模式,也称观察者模式。
1 观察者模式
是使用频率最高的设计模式之一。定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并自动更新。

图 观察者模式UML
Subject,目标类。是指被观察的对象,在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供了一系列方法来增加和删除观察者对象,同时定义了通知方法notify(),目标类可以是接口,也可以是抽象或具体类。
ConcreteSubject,具体目标。是目标类的子类,通常包含有经常发生改变的数据。当它当状态发生改变时,向其各个观察者发出通知。同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有)。如果无须扩展目标类,则具体目标类可以省略。
Observer,观察者。观察者将对观察目标的改变做出反应。观察者一般定义为接口。该接口声明了更新数据的方法update()。
ConcreteObserver,具体观察者。实现了Observer中声明的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合或通过detach()方法将自己从目标类的集合中删除。
public interface Observer {void update(String message);
}public class MessageSubject {private final List<Observer> observerList = new ArrayList<>();public void attach(Observer observer) {this.observerList.add(observer);}public void detach(Observer observer) {this.observerList.remove(observer);}public void notifyObservers(String message) {for (Observer observer : observerList) {observer.update(message);}}}public class AppletMessageSubject extends MessageSubject {@Overridepublic void notifyObservers(String message) {super.notifyObservers(message);System.out.println("小程序平台日志记录,消息发送成功:" + message);}
}public class ApiObserver implements Observer{@Overridepublic void update(String message) {System.out.println("商品推送开始:" + message);}}public class UserObserver implements Observer{@Overridepublic void update(String message) {System.out.println("好的。我知道了,我准备购买:" + message);}
}public class ShopWeb {public static void main(String[] args) {MessageSubject subject = new AppletMessageSubject();Observer userObserver = new UserObserver();Observer apiObserver = new ApiObserver();subject.attach(userObserver);subject.attach(apiObserver);subject.notifyObservers("IPhone 15");subject.notifyObservers("Mate 16");}}//好的。我知道了,我准备购买:IPhone 15
//商品推送开始:IPhone 15
//小程序平台日志记录,消息发送成功:IPhone 15
//好的。我知道了,我准备购买:Mate 16
//商品推送开始:Mate 16
//小程序平台日志记录,消息发送成功:Mate 16
1.1 JDK 对观察者模式的支持
在JDK的java.util包中,提供了Observable类以及Observer接口,它们构成了JDK 对观察者模式的支持。

图 Observable的域与方法

图 Observer 接口
需求:求职者订阅了某boss招聘软件职位发布信息,当有新的职位发布时,会通知给求职者。求职者收到信息后,投递简历。
public class BossObservable extends Observable {@Overridepublic void notifyObservers(Object arg) {super.setChanged();super.notifyObservers(arg);System.out.println("记录日志,职位信息推送成功:" + arg);}
}public class EmployeeObserver implements Observer {private String name;public EmployeeObserver(String name) {this.name = name;}@Overridepublic void update(Observable o, Object arg) {System.out.println(name + "。我钟意这个岗位:" + arg);}}public class Market {public static void main(String[] args) {Observable bossJob = new BossObservable();Observer employee1 = new EmployeeObserver("小李");Observer employee2 = new EmployeeObserver("小吴");bossJob.addObserver(employee1);bossJob.addObserver(employee2);bossJob.notifyObservers("Java 开发");bossJob.notifyObservers("全栈开发");}}//小吴。我钟意这个岗位:Java 开发
//小李。我钟意这个岗位:Java 开发
//记录日志,职位信息推送成功:Java 开发
//小吴。我钟意这个岗位:全栈开发
//小李。我钟意这个岗位:全栈开发
//记录日志,职位信息推送成功:全栈开发
2 优缺点
优点:
1)在观察目标和观察者之间建立一个抽象的耦合。观察目标只需维持一个抽象观察者集合,无须了解其具体观察者。
2)观察者模式支持广播通信,观察目标会向所有已注册的观察者对象发送通知。
缺点:
1)如果一个观察目标对象有许多观察者,将所有观察者都通知到会花费很多时间。
2)如果在观察者和观察目标之间存在循环依赖,观察目标会触发它们之间进行循环调用,可能导致系统奔溃。
3 适用场景
1)一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象及具体的对象。
2)需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象…可以使用观察者模式创建一种链式触发机制。
相关文章:
观察者模式-对象间的联动
有个商城小程序,用户希望当有新品上市的时候能通知他们。这样用户就可以不要时刻盯着小程序了。在这个场景中,用户向小程序订阅了一个服务——发送新品短信。小程序在有新品上线时负责向订阅客户发出这个消息。 这就是发布-订阅模式,也称观察…...
Webpack十大缺点:当过度工程化遇上简单的静态页面
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...
新手指南|如何快速参与Moonbeam Ignite
Moonbeam Ignite是社区熟悉的有奖链上交互活动,将有300万枚GLMR作为生态激励注入Moonbeam生态系统,体验MoonbeamMoonbeam生态的应用即可获取相应Token奖励。Beamex/Beamswap、Moonwell和Gamma作为首批参与Moonbeam Ignite的三家项目方,将在活…...
VR航天科普主题公园模拟太空舱体验馆vr航天模拟体验设备
VR航天航空体验馆巡展是一项非常受欢迎的展览活动,可以让公众在现场体验到航天飞行的乐趣。 普乐蛙VR展览组织者会设计一个航天航空主题的VR体验馆,并在馆内设置各种航天航空相关的展示内容,如太空舱、火箭发射、星际航行等。 其次࿰…...
Spring Boot OAuth 2.0整合详解
目录 一、Spring Boot 2.x 示例 1、初始化设置 2、设置重定向URI 3、配置 application.yml 4、启动应用程序 二、Spring Boot 2.x 属性映射 二、CommonOAuth2Provider 三、配置自定义提供者(Provider)属性 四、覆盖 Spring Boot 2.x 的自动配置…...
安装visual studio报错“无法安装msodbcsql“
在安装visual studio2022时安装完成后提示无法安装msodbcsql, 查看日志文件详细信息提示:指定账户已存在。 未能安装包“msodbcsql,version17.2.30929.1,chipx64,languagezh-CN”。 搜索 URL https://aka.ms/VSSetupErrorReports?qPackageIdmsodbcsql;PackageActi…...
webGL编程指南 第三章 矩阵平移三角形.translatedTriangle_Matrix
我会持续更新关于wegl的编程指南中的代码。 当前的代码不会使用书中的缩写,每一步都是会展开写。希望能给后来学习的一些帮助 git代码地址 :git 接着 上一节 中 我们使用矩阵进行旋转,这次我们使用矩阵实现位移 <!DOCTYPE html> <…...
修改echarts的tooltip样式 折线图如何配置阴影并实现渐变色和自适应
图片展示 一、引入echarts 这里不用多解释 vue里使用 import echarts from “echarts”; html页面引用js文件或用script标签引用 二、定义一个具有宽高的dom div <div id"echart-broken" style"width:400px;height: 200px;"></div>三、定义…...
[论文笔记] SurroundOcc: Multi-Camera 3D Occupancy Prediction for Autonomous Driving
Wei, Yi, et al. “Surroundocc: Multi-camera 3d occupancy prediction for autonomous driving.” Proceedings of the IEEE/CVF International Conference on Computer Vision. 2023. 重点记录 将占用网格应用到多个相机构成的3D空间中; 使用BEVFormer中的方法获取3D特征, …...
辅助驾驶功能开发-功能对标篇(16)-NOA 城市辅助系统-毫末智行
1.横向对标参数 厂商毫末智行车型魏牌摩卡DHT-PHEV上市时间发布:2022年8月30日 上市:2022年底前方案12V5R2L+1DMS摄像头前视摄像头*3【800W】侧视摄像头*4后视摄像头*1【800W】环视摄像头*4DMS摄像头*1雷达毫米波雷达*54D毫米波雷达/超声波雷达*12激光雷达*2【速腾聚创 M1,1…...
H3C的IRF堆叠互联关系说明
H3C IRF堆叠互联说明48口交换机连接方式IRF Port 两台设备第一台的51口 第二台的51口irf-port 1/2 port group interface ten-gigabitethernet 1/0/51 port group interface ten-gigabitethernet 1/0/52第一台的52口第二台的52口irf-port 2/1 port group interface ten-gigabi…...
货物摆放(蓝桥杯)
货物摆放 题目描述 小蓝有一个超大的仓库,可以摆放很多货物。 现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所有的…...
3782: 【C3】【穷举】弹珠游戏
目录 题目描述 输入 输出 样例输入 样例输出 题目描述 游戏的内容是:在一个 n*n 的矩阵里,有若干个敌人,你的弹珠可以摧毁敌人,但只能攻击你所在的行、列里的所有敌人,然后你就可以获得他们的分数之和࿰…...
leetcode 5
leetcode 5 题目是通过枚举字符串,然后判断是否子字符串满足回文。 引用传递和值传递相比,引用传递可以减少内存空间。提高代码运行效率。 https://www.cnblogs.com/yanlingyin/archive/2011/12/07/2278961.html...
centos中nacos设置开机自启动
以下实践亲测有效! 1、在以下目录编辑新建nacos.service文件 vim /lib/systemd/system/nacos.service [Unit] Descriptionnacos Afternetwork.target [Service] Typeforking ExecStart/usr/local/nacos/bin/startup.sh -m standalone ExecReload/usr/local/nacos/b…...
双指针——移动零
一,题目要求: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0…...
WPF中在MVVM模式下实现导航功能
WPF中在MVVM模式下实现导航功能 一、利用TabControl 使用场景:项目小,不用考虑内存开销的问题。 实现方式1-手动指定ViewModel 分别定义3个UserControl作为View用于演示 <UserControl...><Grid><StackPanel Orientation"Vertic…...
SpringBoot面试题2:SpringBoot与SpringCloud 区别?SpringBoot和Spring、SpringMVC的区别
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:SpringBoot与SpringCloud 区别? Spring Boot 和 Spring Cloud 是 Spring 生态系统中的两个关键组件,它们有以下区别: 定位:Spring Boot 用于简…...
Practical Deep Raw Image Denoisingon Mobile Devices
Abstract 近年来,基于深度学习的图像去噪方法得到了广泛的研究,并在许多公共基准数据集中盛行。然而,最先进的网络计算成本太高,无法直接应用于移动设备。在这项工作中,我们提出了一种轻量级、高效的基于神经网络的原…...
如何在Android项目中制作和使用三方包(jar文件)
文章目录 1 概念介绍2 制作方法2.1 制作步骤2.2 制作结果3 使用方法3.1 具体步骤3.2 示例代码4 内容总结在项目中为了跨部门协作需要把相关的内容打成包文件,基于这个需求,我们将介绍如何把 代码制作成三方包,这里的三方包是指jar文件。同时也会介绍如何在Android项目中使用…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
