观察者模式的理解和实践
引言
在软件开发中,设计模式是开发者们为了解决常见的设计问题而总结出来的一系列最佳实践。观察者模式(Observer Pattern)是其中一种非常经典且使用率极高的设计模式。它主要用于定义对象之间的一对多关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。观察者模式广泛应用于GUI系统、订阅发布系统等场景,因为它能够有效实现解耦,降低对象之间的依赖性,使系统更加灵活和可扩展。

一、观察者模式的概念
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新。
观察者模式的核心要素包括:
- 主题(Subject):也称为被观察者,它维护一个观察者列表,并在状态发生变化时通知所有观察者。
- 观察者(Observer):它定义一个更新接口,用于接收主题通知的变化。
- 具体主题(Concrete Subject):实现主题接口,维护观察者列表并通知它们状态的变化。
- 具体观察者(Concrete Observer):实现观察者接口,接收主题的通知并进行相应的更新。
二、观察者模式的优点和适用场景
优点
- 解耦:观察者模式将被观察者和观察者解耦,使得它们之间的依赖性更小,甚至做到毫无依赖。这大大提高了系统的灵活性和可扩展性。
- 动态更新:观察者模式支持动态添加和删除观察者,这使得系统能够在运行时根据需要动态调整观察者的数量。
- 广播通信:当一个对象的状态发生变化时,它会自动通知所有依赖的对象,这种广播通信机制非常适合用于事件驱动编程。
适用场景
- GUI系统:在图形用户界面(GUI)编程中,按钮、文本框等控件的事件处理通常使用观察者模式。控件作为被观察者,当用户进行操作时,会通知观察者(即事件处理器或监听器)来处理相应的事件。
- 订阅发布系统:观察者模式是发布-订阅系统的基础。在这种系统中,发布者发布消息,订阅者订阅感兴趣的消息类型。当某个消息类型被发布时,订阅者会收到通知并执行相应的处理逻辑。
- 数据模型与视图同步:在模型-视图-控制器(MVC)架构中,观察者模式通常用于数据模型和视图之间的更新同步。当模型中的数据发生变化时,所有依赖该模型的视图都会自动更新显示。
- 股票市场监测:在金融系统中,股票价格可能频繁变动,多个不同的系统(如显示价格的终端、交易系统等)都依赖这些变化。观察者模式可以让股票价格的变化自动通知所有依赖该数据的系统。
三、Java实现观察者模式
下面我们通过Java代码来演示如何实现观察者模式。
1. 定义被观察者接口(Subject)
public interface Subject {void addObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers();
}
2. 定义观察者接口(Observer)
public interface Observer {void update(String message);
}
3. 实现具体主题(Concrete Subject)
import java.util.ArrayList;
import java.util.List;public class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();private String state;@Overridepublic void addObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer observer : observers) {observer.update(state);}}public void setState(String state) {this.state = state;notifyObservers();}public String getState() {return state;}
}
4. 实现具体观察者(Concrete Observer)
public class ConcreteObserver implements Observer {private String name;public ConcreteObserver(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " received message: " + message);}
}
5. 演示代码
public class ObserverPatternDemo {public static void main(String[] args) {// 创建主题对象ConcreteSubject subject = new ConcreteSubject();// 创建观察者对象ConcreteObserver observer1 = new ConcreteObserver("Observer 1");ConcreteObserver observer2 = new ConcreteObserver("Observer 2");// 注册观察者subject.addObserver(observer1);subject.addObserver(observer2);// 改变主题状态,通知观察者subject.setState("State 1");subject.setState("State 2");// 移除一个观察者subject.removeObserver(observer1);// 再次改变主题状态,只通知剩余的观察者subject.setState("State 3");}
}
运行结果
Observer 1 received message: State 1
Observer 2 received message: State 1
Observer 1 received message: State 2
Observer 2 received message: State 2
Observer 2 received message: State 3
四、观察者模式的实践
在实际开发中,观察者模式的应用非常广泛。以下是一些具体的实践案例:
-
GUI事件监听:在Java Swing或JavaFX等GUI框架中,按钮、文本框等控件的事件处理通常使用观察者模式。控件作为被观察者,当用户进行操作时,会通知观察者(即事件处理器或监听器)来处理相应的事件。
-
数据模型和视图同步:在MVC架构中,数据模型的变化需要实时同步到视图上。可以使用观察者模式,让数据模型作为被观察者,视图作为观察者。当数据模型发生变化时,会自动通知所有视图进行更新。
-
股票价格监控:在金融系统中,股票价格可能频繁变动。可以使用观察者模式,让股票价格作为被观察者,所有依赖股票价格的系统(如显示价格的终端、交易系统等)作为观察者。当股票价格发生变化时,会自动通知所有依赖的系统进行更新。
-
消息队列系统:在消息队列系统中,生产者将消息发送到队列中,消费者作为观察者订阅队列以接收和处理消息。可以使用观察者模式,让队列作为被观察者,消费者作为观察者。当有新消息到达队列时,会自动通知所有订阅的消费者进行处理。
总结
观察者模式是一种非常经典且实用的设计模式,它定义了一种一对多的依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。观察者模式在GUI系统、订阅发布系统、数据模型与视图同步等场景中有着广泛的应用。通过Java代码实现观察者模式,我们可以更加深入地理解这一设计模式的原理和应用方法。希望本文能够帮助读者更好地掌握观察者模式,并在实际开发中灵活运用这一设计模式来解决问题。
相关文章:
观察者模式的理解和实践
引言 在软件开发中,设计模式是开发者们为了解决常见的设计问题而总结出来的一系列最佳实践。观察者模式(Observer Pattern)是其中一种非常经典且使用率极高的设计模式。它主要用于定义对象之间的一对多关系,使得当一个对象的状态发…...
查看Windows系统上的Redis服务器是否设置了密码
查看 Redis 配置文件 1.找到 Redis 配置文件: 通常Redis配置文件名为 redis.windows.conf 或 redis.conf,它位于Redis安装目录中。 2.打开配置文件: 使用文本编辑器(如Notepad、VS Code等)打开该文件。 3.查找 re…...
认识Java中的异常(半成品)
1.异常的概念与体系结构 1.1在Java中,将程序执行过程中发生的不正常行为称为异常.比如 1.算数异常 public class Main1 {public static void main(String[] args){System.out.println(10/0);} } //异常信息为:Exception in thread "main" java.lang.ArithmeticExc…...
生成SSH秘钥文件
git生成文件命令 # 配置用户名和邮箱 git config --global user.name "你的GitHub用户名" git config --global user.email "你的GitHub邮箱"# 生成ssh-key ssh-keygen -t rsa -C “你的GitHub邮箱" # 验证 ssh -T gitgithub .com 第一步:…...
wsl2子系统ubuntu发行版位置迁移步骤
默认的wsl2发行版是安装在windos的c盘,占用空间较大,有迁移需求,也可以迁移到其他电脑; 查看现有发行版信息 运行以下命令查看现有的 WSL 发行版及其状态: wsl --list --verbose# 输出示例NAME STATE …...
协程设计原理与实现
协程设计原理与汇编实现 同步与异步 对于任何一个事情,都可以划分为不同的步骤。所谓同步,就先做第一个事情,按照这件事的步骤完成这件事之后,再去做第二件事。再去做第三件事,以此类推。 异步就是,可以…...
合并区间C和C++的区别、布尔、整型、浮点、指针类型和0做比较、malloc、calloc、realloc的区别
56. 合并区间 class Solution { public:vector<vector<int>> merge(vector<vector<int>>& intervals) {//先按照每个区间的左元素排序,这样每个区间的左边界就固定了,所以之后考虑相邻的//区间是否是相交的就行 类似与栈的…...
Flutter 图片编辑板(一) 事件路由
一个图片编辑板,有两部分组成。编辑板和内容项。每一个内容项是被InteractiveViewer修饰的widget,具有缩放偏移的功能。 在图片编辑板上, 会有多个内容相,图片或文字(添加文字目前还没做过)。 当要编辑其中…...
【Java】—— 图书管理系统
基于往期学习的类和对象、继承、多态、抽象类和接口来完成一个控制台版本的 “图书管理系统” 在控制台界面中实现用户与程序交互 任务目标: 1、系统中能够表示多本图书的信息 2、提供两种用户(普通用户,管理员) 3、普通用户…...
数据库基础入门:从零开始学习数据库的核心概念
数据库是现代软件开发的核心组成部分之一,无论是网站、手机应用还是企业管理系统,都离不开数据库的支持。本文将带你从零开始,逐步了解数据库的基本概念和常见操作。 什么是数据库? 数据库(Database)是一个…...
Y20030002 微信+Java+Jsp+Servlet+MySQL的问卷调查小程序的设计与实现 源代码 配置文档 全套资料
问卷调查微信小程序 1.摘要2. 系统开的背景和意义3. 国内外研究现状4. 系统功能5.界面展示6.源码获取 1.摘要 摘 要:本文深入研究并实现了一个基于微信小程序的问卷调查系统。微信小程序问卷调查系统借助于微信小程序的便捷性和普及性,为用户提供了一个…...
ros项目dual_arm_pick-place(urdf文件可视化查看)
前言 一直想写一些项目的讲解,今天(2024.12.05)可以说正式开始了。 dual_arm_pick-place项目,是关于两个机械臂协同传递物品。 正文 这次的话,给大家讲一下里面的urdf文件。 这篇文章主要来看一下项目中的urdf文件…...
AI-安全-B站
1 需求 百度-林道正-《大模型合规探索》火山引擎-林泽韬-《大模型安全挑战与防护实践》Chamd5-bayuncao-《基于RAG的AI代码审计框架》德国电信咨询有限公司-杨麟-《AI在SOC中的应用发展》360-李亚青-《以模制模,大模型安全的解决之道》金晴云华-富吉祥-《安全大脑在…...
【C#设计模式(19)——备忘录模式(MementoPattern)】
前言 备忘录模式:将想要备份的信息交给备忘录对象来管理。通过设置初始、备份、修改、恢复等状态展示备忘录模式的使用。 代码 //备忘录类 public class Memento {private string state;public string State { get>state;}public Memento(string state){this.st…...
第三部分:进阶概念 8.事件处理 --[JavaScript 新手村:开启编程之旅的第一步]
JavaScript 事件处理是 Web 开发中不可或缺的一部分,它允许开发者响应用户的交互行为(如点击、键盘输入等)或浏览器的行为(如页面加载完成)。通过事件处理,我们可以使网页更加动态和互动。以下是关于 JavaS…...
工具推荐-js爬取工具
现在测试方向都偏向于从js中的接口来入手找到可以进的点,关于快速扫描js文件来发现敏感接口的工具有很多,下面的jjjjs就是其一 项目地址: GitHub - ttstormxx/jjjjjjjjjjjjjs: 爬网站JS文件,自动fuzz api接口,指定api接口&#x…...
Android问题记录 - Inconsistent JVM-target compatibility detected for tasks
文章目录 前言开发环境问题描述问题分析解决方案补充内容最后 前言 前段时间升级Android Studio后修复了一堆问题,详情请看:Android问题记录 - 适配Android Studio Ladybug/Java 21/AGP 8.0(持续更新)。我以为问题已经全部解决了…...
ejb组件(rmi) webservice平台(xml)
springboot bean 在 Spring Boot 中,Bean 是 Spring 框架的核心概念之一,表示由 Spring 容器管理的对象。通过 Bean 或其他注解(如 Component、Service、Repository 等)来定义和管理这些对象。以下是关于 Spring Boot 中 Bean 的…...
【jvm】垃圾回收的重点区域
目录 1. 说明2. 堆(Heap)3. 方法区(Method Area) 1. 说明 1.JVM(Java Virtual Machine)垃圾回收的重点区域主要集中在堆(Heap)和方法区(Method Area)。2.堆是…...
PyQt信号槽实现页面的登录与跳转 #页面进一步优化
将登录框中的取消按钮使用信号和槽的机制,关闭界面。 将登录按钮使用信号和槽连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admin",密码是否为"123456",如果账号密码匹配成功,当前界面关…...
Fix | Resolving ImportError: libGL.so.1 Missing in Docker/Local Environments
1. 遇到libGL.so.1缺失报错怎么办? 最近在部署一个基于OpenGL的图形处理项目时,又双叒叕遇到了这个熟悉的报错:"ImportError: libGL.so.1: cannot open shared object file: No such file or directory"。这已经是这个月第三次碰到…...
PyTorch 2.8镜像真实效果:物理实验→电磁场/流体力学可视化视频
PyTorch 2.8镜像真实效果:物理实验→电磁场/流体力学可视化视频 1. 开箱即用的专业级物理模拟环境 当你第一次启动这个基于RTX 4090D优化的PyTorch 2.8镜像时,最直接的感受就是"专业工具就该这样"。这个镜像不是普通的深度学习环境ÿ…...
SDXL 1.0电影级绘图工坊:RTX 4090专属,5分钟零基础部署教程
SDXL 1.0电影级绘图工坊:RTX 4090专属,5分钟零基础部署教程 1. 为什么选择SDXL 1.0电影级绘图工坊 如果你正在寻找一款能在RTX 4090上发挥极致性能的AI绘图工具,SDXL 1.0电影级绘图工坊绝对是你的不二之选。这款工具专为4090显卡优化&#…...
GT New Horizons材质包精选:10款提升沉浸体验的视觉升级方案
GT New Horizons材质包精选:10款提升沉浸体验的视觉升级方案 【免费下载链接】GT-New-Horizons-Modpack A big progressive questing modpack for Minecraft 1.7.10 balanced around the mod GregTech. 项目地址: https://gitcode.com/GitHub_Trending/gt/GT-New-…...
Potree 点云可视化实战指南:从基础配置到高级测量技巧
1. Potree点云可视化入门指南 第一次接触Potree时,我被它处理海量点云数据的能力震撼到了。这个基于WebGL的开源库,能让普通浏览器流畅渲染上亿级别的点云数据。想象一下,不用安装专业软件,打开网页就能查看精细的激光扫描模型&am…...
TradingAgents-CN:基于多智能体LLM的中文金融交易决策框架技术指南
TradingAgents-CN:基于多智能体LLM的中文金融交易决策框架技术指南 【免费下载链接】TradingAgents-CN 基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版 项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN 项目价值定位&…...
C++的std--ranges容错系统
C的std::ranges容错系统:现代编程的稳健之道 在C20标准中,std::ranges库的引入彻底改变了算法与容器的交互方式,其容错机制为开发者提供了更安全、更灵活的编程体验。传统迭代器容易因越界或无效操作导致未定义行为,而std::range…...
ProfControl V8的介绍 阵列生成
作者:刘凌波链接:环野电子, profcontrolhttp://oa.profcontrol.cn/teaching_V8-7926f783c6.html来源:ProfControl阵列生成ProfControl支持基于仿射变换的阵列快速生成方式,ProfControl支持对各种对象进行阵列生产(包括…...
10分钟掌握Deep-Live-Cam:从零搭建实时AI换脸系统的完整指南
10分钟掌握Deep-Live-Cam:从零搭建实时AI换脸系统的完整指南 【免费下载链接】Deep-Live-Cam real time face swap and one-click video deepfake with only a single image 项目地址: https://gitcode.com/GitHub_Trending/de/Deep-Live-Cam Deep-Live-Cam是…...
毕业查重不踩坑!Paperxie 免费查重,给毕业生的安心 buff
paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/checkhttps://www.paperxie.cn/check 又是一年毕业季,当毕业论文的最后一个句号落下,查重就成了横亘在无数本科生面前的 “毕业拦路虎”。多少人熬了几…...
