观察者模式的理解和实践
引言
在软件开发中,设计模式是开发者们为了解决常见的设计问题而总结出来的一系列最佳实践。观察者模式(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",如果账号密码匹配成功,当前界面关…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...