当前位置: 首页 > news >正文

设计模式二十:观察者模式(Observer Pattern)

定义了一种一对多的依赖关系,允许多个观察者(也称为订阅者)对象同时监听一个主题对象,当主题对象发生变化时,所有依赖于它的观察者都会收到通知并自动更新。

观察者模式的使用场景

观察者模式在许多场景中都可以发挥作用,特别是在需要解耦和实现对象间动态通信的情况下

  1. 事件处理和 GUI:
    在图形用户界面(GUI)应用中,用户界面元素(如按钮、文本框)可以作为观察者,而事件(如点击按钮)可以作为主题,以实现用户界面与业务逻辑之间的解耦。
  2. 订阅/发布模型:
    观察者模式常被用于实现发布/订阅模型,其中发布者是主题,订阅者是观察者。这在消息队列系统、事件总线等场景中非常有用,允许消息的生产者发布消息,而消费者订阅并处理消息。
  3. 通知和提醒系统:
    观察者模式可以用于实现通知和提醒系统。例如,在一个新闻网站中,当有新的新闻发布时,订阅了该类新闻的用户会收到通知。
  4. 股票市场分析:
    在金融领域,观察者模式可以用于股票市场分析工具。股票价格的变化可以作为主题,不同的分析器可以作为观察者,以便在价格变化时及时更新分析结果。
  5. 网络应用中的状态同步:
    在分布式系统或网络应用中,观察者模式可以用于状态同步。当一个节点的状态发生变化时,其他节点可以作为观察者,以便实时更新其本地状态。
  6. 游戏开发:
    在游戏开发中,观察者模式可以用于处理游戏内的事件、状态变化、角色行为等。例如,当一个角色受到伤害时,其他角色可以作为观察者获得相应的通知。
  7. 传感器数据监测:
    在物联网领域,传感器收集到的数据可以作为主题,不同的监测系统可以作为观察者,以便在数据变化时进行监测和报警。

观察者模式涉及的角色

  1. 主题(Subject):
    主题是被观察的对象,它维护一组观察者对象,并提供方法用于添加、删除和通知观察者。主题通常包含状态或数据,当状态变化时会通知所有观察者。
    定义了添加、删除和通知观察者的方法。
    维护一个观察者列表,用于存储注册的观察者。
    当主题状态变化时,调用通知方法以便通知所有注册的观察者。
  2. 具体主题(Concrete Subject):
    具体主题是实际的被观察对象,它继承或实现主题接口,负责实现主题的具体逻辑。它会在状态变化时通知所有已注册的观察者。
    继承或实现主题接口。
    包含需要被观察的状态或数据。
    在状态变化时,调用通知方法来通知所有观察者。
  3. 观察者(Observer):
    观察者是订阅主题状态变化的对象,它定义一个更新方法,当主题状态发生变化时,观察者的更新方法会被调用,从而观察者可以获取最新的信息并执行相应的操作。
    定义了一个更新方法,用于在主题状态变化时被调用。
    观察者通过该方法获取主题最新的状态信息,然后执行相应的操作。
  4. 具体观察者(Concrete Observer):
    具体观察者是实际的观察者对象,它实现了观察者接口的更新方法,以便在主题状态变化时执行特定的操作。
    实现观察者接口的更新方法,以便在主题状态变化时执行具体的操作。
    在更新方法中,根据主题的状态变化来做出响应。

java代码实例

演示了使用观察者模式实现一个天气预报系统

主题接口
package cn.observer.service;public interface Subject {//添加接受这void addObserver(Observer_ observer);//一处接受者void reduceObserver(Observer_ observer);//消息变动void notifyObservers();}

具体主题

//天气驿站
public class WeatherStation implements Subject{private List<Observer_> observers=new ArrayList<>();private float temperature;//天气温度@Overridepublic void addObserver(Observer_ observer) {this.observers.add(observer);}@Overridepublic void reduceObserver(Observer_ observer) {this.observers.remove(observer);}@Overridepublic void notifyObservers() {for (Observer_ observer: observers) {observer.recept(this.temperature);}}public void setTemperature(float temperature) {this.temperature = temperature;notifyObservers();}}

观察者接口

//天气广播台public interface Observer_ {void recept(float temperature);}

具体观察者

public class WeatherDisplay implements Observer_{@Override    public void recept(float temperature) {System.out.println("当前温度:"+temperature+"度");    }
}

客户端

public class Observer {public static void main(String[] args) {WeatherStation station = new WeatherStation();WeatherDisplay display = new WeatherDisplay();station.addObserver(display);station.setTemperature(25.5f);station.reduceObserver(display);station.setTemperature(30.0f); }}

输出结果

当前温度:25.5度

观察者模式的优缺点

优点:

  1. 解耦性:
    观察者模式可以将主题对象与观察者对象之间的依赖关系解耦,使它们可以独立变化,不会相互影响。
  2. 灵活性和可扩展性:
    由于主题和观察者之间的关系是松耦合的,可以轻松添加新的观察者或修改现有的观察者,而不需要修改主题。
  3. 一对多通信:
    观察者模式允许一个主题同时通知多个观察者,这在实现发布/订阅模型、事件处理和消息传递等场景中非常有用。
  4. 可维护性:
    观察者模式使系统中的各个部分更容易理解和维护,因为它将复杂的交互逻辑分解为独立的观察者对象。
  5. 支持动态添加和移除观察者:
    可以动态地注册和注销观察者,使系统更加灵活。

缺点:

  1. 内存泄漏:
    如果观察者没有正确注销,它们仍然会保留对主题的引用,可能导致内存泄漏。
  2. 不当使用带来复杂性:
    过多或不合理地使用观察者模式可能会导致系统复杂化,降低可维护性。因此,在设计时需要权衡使用。
  3. 顺序问题:
    观察者模式中观察者的通知顺序是不确定的,这可能导致一些问题,特别是在观察者之间有相互依赖关系时。
  4. 性能问题:
    当观察者数量庞大且通知频繁时,可能会影响性能。因此,在高性能要求的系统中需要谨慎使用。

相关文章:

设计模式二十:观察者模式(Observer Pattern)

定义了一种一对多的依赖关系&#xff0c;允许多个观察者&#xff08;也称为订阅者&#xff09;对象同时监听一个主题对象&#xff0c;当主题对象发生变化时&#xff0c;所有依赖于它的观察者都会收到通知并自动更新。 观察者模式的使用场景 观察者模式在许多场景中都可以发挥…...

Linux操作系统--CentOS使用初体验

我们安装好Linux的操作系统之后,下面就可以使用Linux操作系统了。我们一起来看看如何使用。 (1).桌面 我们在进入CentOS操作系统后可以发现一些和Windows操作系统相类似的情况。如:网络、时间显示、以及基本的软件等内容。 --创建文件、文件夹。 (2).操作终端 Linux中的终…...

搭建HAProxy + Keepalived高可用

安装 在四台虚拟机上&#xff0c;我们以如下方式搭建集群&#xff1a; 192.168.115.3 haproxykeepalived 192.168.115.4haproxykeepalived 192.168.115.5 nginx 192.168.115.6 nginx 在192.168.115.3 和192.168.115.4 上安装haproxy和keepalived&#xff08;haproxy编译安装…...

使用Python爬虫定制化开发自己需要的数据集

在数据驱动的时代&#xff0c;获取准确、丰富的数据对于许多项目和业务至关重要。本文将介绍如何使用Python爬虫进行定制化开发&#xff0c;以满足个性化的数据需求&#xff0c;帮助你构建自己需要的数据集&#xff0c;为数据分析和应用提供有力支持。 1.确定数据需求和采集目…...

java八股文面试[java基础]——接口和抽象类的区别

知识来源&#xff1a; 【基础】接口和抽象类_哔哩哔哩_bilibili 【2023年面试】Java中抽象类和接口有什么区别_哔哩哔哩_bilibili 【23版面试突击】抽象类和接口的区别&#xff0c;类可以继承多个类么&#xff0c;接口可以继承多个接口么,类可以实现多个接口么&#xff1f;_…...

head 请求了解过吗?如何用 get 模拟 head 请求?不需要服务器返回数据,怎么实现?

HEAD请求是HTTP/1.1协议中定义的一个请求方法&#xff0c;与GET请求相似&#xff0c;但只请求目标URL的头部&#xff0c;不请求实际的数据或者说正文内容。其主要用途是&#xff1a; 检查资源是否存在。获取资源的元数据&#xff08;如响应头中的Content-Length或Last-Modifie…...

Redis笔记——(狂神说)待续

Nosql概述 为什么要用NoSql&#xff1f; 1、单机mysql的年代&#xff1a;90年代&#xff0c;网站访问量小&#xff0c;很多使用静态网页html写的&#xff0c;服务器没压力。 当时瓶颈是&#xff1a;1)数据量太大一个机器放不下。2)数据的索引(BTree)&#xff0c;一个机器内存也…...

基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v7.0版已发布

关于MobileIMSDK MobileIMSDK 是一套专门为移动端开发的开源IM即时通讯框架&#xff0c;超轻量级、高度提炼&#xff0c;一套API优雅支持 UDP 、TCP 、WebSocket 三种协议&#xff0c;支持 iOS、Android、H5、标准Java、小程序、Uniapp&#xff0c;服务端基于Netty编写。 工程…...

BLFS学习系列 第26章. 显示管理器 —— 总述

显示管理器&#xff08;Display Manager&#xff09;是用于启动图形显示&#xff08;当前为X服务器&#xff09;并为窗口管理器或桌面环境提供登录功能的图形程序。 有许多显示管理器可用。一些较为知名的包括&#xff1a;GDM、KDM&#xff08;已弃用&#xff09;、LightDM、L…...

macOS上编译obs-studio

前言 最近基于obs的1个二开程序&#xff0c;需要移植到macOS平台上&#xff0c;由于遇到些问题&#xff0c;本文记录下如何在macOS上配置&编译&运行obs程序完整过程。 下载 首先下载cmake-gui工具&#xff0c;下载CMAKE&#xff0c;选择对应macOS平台的cmake版本&…...

Oracle数据库快速入门

前言&#xff1a; 我想现在很多人的入门数据库都是mysql&#xff0c;但是由于工作中会接触到Oracle数据库&#xff0c;如果你有MySQL的基础的话&#xff0c;这篇文章能让你很快掌握Oracle。 目录 1.体系结构 2.创建用户和表空间 2.1.创建表空间 2.2.创建用户 3.数据类型…...

Linux内核学习(十)—— 块 I/O 层(基于Linux 2.6内核)

目录 一、剖析一个块设备 二、缓冲区和缓冲区头 三、bio 结构体 四、请求队列 五、I/O 调度程序 系统中能够随机&#xff08;不需要按顺序&#xff09;访问固定大小数据片&#xff08;chunks&#xff09;的硬件设备称作块设备&#xff0c;这些固定大小的数据片就称作块。最…...

SpringMVC 写个 HelloWorld

文章目录 一、SpringMVC简介1、什么是MVC2、什么是SpringMVC3、SpringMVC的特点 二、HelloWorld1、开发环境2、创建maven工程a>添加web模块b>打包方式&#xff1a;warc>引入依赖 3、配置web.xmla>默认配置方式b>扩展配置方式 4、创建请求控制器5、创建springMVC…...

ARM--day7(cortex_M4核LED实验流程、异常源、异常处理模式、异常向量表、异常处理流程、软中断编程、cortex_A7核中断实验)

软中断代码&#xff1a;&#xff08;keil软件&#xff09; .text .global _start _start:1.构建异常向量表b resetb undef_interruptb software_interruptb prefetch_dataabortb data_abortb .b irqb fiq reset:2.系统一上电&#xff0c;程序运行在SVC模式1>>初始化SVC模…...

Java中LinkList的基本介绍和细节讨论。双向链表的代码和LinkList的源码。LinkList和ArrayList的比较与选择。

LinkedList 是 Java 中的一个双向链表实现的类&#xff0c;它实现了 List 接口&#xff0c;同时也实现了 Deque 接口&#xff0c;因此可以用作列表、队列或双端队列。下面是关于 LinkedList 的基本介绍和细节讨论&#xff1a; 基本介绍&#xff1a; LinkedList 是一个双向链表…...

Proteus软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 Proteus软件是一款电路设计和仿真的综合性软件&#xff0c;由Labcenter公司开发。它提供了一个交互式的图形界面&#xff0c;用户可以在其中构建电路、仿真结果并实时观察仿真结果。 1、Proteus的历史和演变 Proteus软件最初于…...

“图为科技——什么是边缘计算“

边缘计算是一种新兴的计算模式&#xff0c;它将计算资源和服务推向离终端设备更近的地方。以往&#xff0c;计算任务大多集中在云端进行&#xff0c;但随着物联网和移动互联网的快速发展&#xff0c;边缘计算应运而生。 边缘计算的核心思想是将计算、存储和网络功能部署在离终端…...

SpringCloud教程 | 第六篇: 分布式配置中心(Spring Cloud Config)

在上一篇文章讲述zuul的时候&#xff0c;已经提到过&#xff0c;使用配置服务来保存各个服务的配置文件。它就是Spring Cloud Config。 一、简介 在分布式系统中&#xff0c;由于服务数量巨多&#xff0c;为了方便服务配置文件统一管理&#xff0c;实时更新&#xff0c;所以需…...

mysql 错误码

一、 #22001 Caused by: java.sql.BatchUpdateException: Data truncation: #22001检查一下数据库表字段&#xff0c;特别是VARCHAR的长度是否够。 Caused by: java.sql.BatchUpdateException: #HY000检查是不是违反了非空约束&#xff0c;NOT NULL字段有没有没传的 二、...

HTML的form表单标签详解~

通过HTML提交表单数据有web中是非常常用的操作&#xff0c;所以有必要详细、仔细学习了解HTML的form表单。 目录 01-关键词 novalidate 是什么意思&#xff1f;02- action"" 是什么意思&#xff1f;03- enctype"multipart/form-data" 是什么意思&#xff1…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...

python打卡day49@浙大疏锦行

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...

作为点的对象CenterNet论文阅读

摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表&#xff0c;并对每一个位置进行分类。这种做法既浪费又低效&#xff0c;并且需要额外的后处理。在本文中&#xff0c;我们采取了不同的方法。我们将物体建模为单…...