当前位置: 首页 > 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…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...