【设计模式深度剖析】【7】【行为型】【观察者模式】
👈️上一篇:中介者模式
设计模式-专栏👈️
文章目录
- 观察者模式
- 英文原文
- 直译
- 如何理解?
- 观察者模式的角色
- 类图
- 代码示例
- 观察者模式的应用
- 观察者模式的优点
- 观察者模式的缺点
- 观察者模式的使用场景
观察者模式
观察者模式(Observer Pattern)
观察者(Observer)也称发布-订阅(Publish-Subscribe),依赖(Dependents)。
观察者模式就像是一群订阅了报纸的读者,每当报纸有新版发布(状态更新),就会自动送到这些读者的手中,读者们可以根据自己的兴趣选择阅读哪些内容。这样,读者和报纸之间形成了一种灵活、低耦合的订阅-发布关系。
英文原文
The Observer Design Pattern is a behavioral design patternthat defines a one-to-many dependency between objects so that when one object (the subject) changes state, all its dependents (observers) are notified and updated automatically.
直译
观察者设计模式(Observer Design Pattern)是一种行为设计模式,它定义了对象之间的一对多依赖关系,以便当一个对象(主题)改变其状态时,其所有依赖者(观察者)都能得到通知并自动更新。
如何理解?
观察者模式就像是一群朋友在关注一个公告板。公告板是被观察者,而朋友们是观察者。当公告板上的内容发生变化(比如有新的活动通知)时,所有关注这个公告板的朋友们(观察者)都会收到通知,并根据通知的内容做出相应的反应(比如参加活动)。这样,即使公告板的内容经常变化,朋友们也不需要一直盯着它看,只要他们关注了公告板,就能在第一时间得到通知。这种模式不仅方便了朋友们获取信息,也减轻了公告板的负担。
观察者模式的角色
观察者模式通常包含以下几个角色:
- Subject(主题/被观察者):它知道有哪些观察者对其感兴趣,并提供了一个接口让观察者能注册自己、移除自己以及通知它们。
- Observer(观察者):为那些在主题状态改变时需要获得通知的对象定义一个更新接口。
- ConcreteSubject(具体主题):保存有关状态的信息,并提供一个接口供观察者查询状态、注册和移除自己。
- ConcreteObserver(具体观察者):实现观察者接口,以便在主题的状态发生改变时得到更新。
类图
代码示例
package com.polaris.designpattern.list3.behavioral.pattern07.observer.classicdemo;import java.util.ArrayList;
import java.util.List;interface Observer {void update(String message);
}interface Subject {void registerObserver(Observer observer);void removeObserver(Observer observer);void notifyObservers(String message);
}class ConcreteSubject implements Subject {private List<Observer> observers = new ArrayList<>();@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic void removeObserver(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObservers(String message) {for (Observer observer : observers) {observer.update(message);}}// 这里可以添加其他方法来改变状态 public void setState(String state) {// 状态改变时,通知所有观察者 notifyObservers("Subject state has changed to: " + state);}
}class ConcreteObserver implements Observer {private String name;public ConcreteObserver(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " has been notified: " + message);}
}public class ObserverPatternDemo {public static void main(String[] args) {Subject subject = new ConcreteSubject();System.out.println("registerObserver: Observer 1, Observer 2...");Observer observer1 = new ConcreteObserver("Observer 1");Observer observer2 = new ConcreteObserver("Observer 2");subject.registerObserver(observer1);subject.registerObserver(observer2);System.out.println("change subject state...");// 改变主题状态,这将触发所有注册的观察者的update方法 ((ConcreteSubject) subject).setState("New state");// 移除一个观察者System.out.println("remove observer1...");subject.removeObserver(observer1);System.out.println("change subject state...");// 再次改变主题状态,只会通知未移除的观察者 ((ConcreteSubject) subject).setState("Another new state");}
}/* Output:
registerObserver: Observer 1, Observer 2...
change subject state...
Observer 1 has been notified: Subject state has changed to: New state
Observer 2 has been notified: Subject state has changed to: New state
remove observer1...
change subject state...
Observer 2 has been notified: Subject state has changed to: Another new state
*///~
上面示例当主题的状态改变时,所有注册的观察者都会收到通知并更新它们的状态。当某个观察者被移除后,它将不再收到通知。
观察者模式的应用
- 图形用户界面(GUI)开发:在GUI中,当用户与界面上的元素(如按钮、文本框)进行交互时,这些元素的状态可能会发生变化。观察者模式可以用于将这些状态变化通知给相应的观察者,触发相应的操作或更新界面。
- 消息通知系统:在聊天应用、社交媒体平台等需要实时消息传递的场景中,观察者模式可以实现消息的订阅与发布。当有新消息发布时,订阅该消息的观察者将收到通知并进行处理。
- 股票市场:股票交易所可以充当被观察者,而股票交易员可以充当观察者。当股票的价格、交易量等发生变化时,交易员将接收到通知并采取相应的行动。
- 日志记录系统:日志记录器可以充当被观察者,而观察者可以是日志分析器、报警系统等。当日志发生变化时,观察者将收到通知并执行相应的操作,如生成报告、发送警报等。
观察者模式的优点
- 解耦:观察者和被观察者是抽象耦合的,降低了它们之间的依赖关系,使得系统更加灵活和可扩展。
- 广播通信:支持一对多的依赖关系,简化了系统设计。
- 满足开闭原则:增加新的具体观察者或观察目标时,无需修改原有系统代码。
观察者模式的缺点
- 性能问题:如果一个被观察者对象有很多的直接和间接的观察者,将所有的观察者都通知到会花费很多时间,可能导致性能下降。
- 循环依赖问题:如果观察者和观察目标之间存在循环依赖,可能导致系统崩溃。
- 缺乏细节:观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
观察者模式的使用场景
- 当一个对象的改变需要同时改变其他对象时:可以使用观察者模式,将需要改变的对象作为观察者,将发生变化的对象作为被观察者。
- 当一个对象必须通知其他对象,但又不希望这些对象与它形成紧密耦合时:通过观察者模式,可以实现对象之间的松耦合关系。
👈️上一篇:中介者模式
设计模式-专栏👈️
相关文章:

【设计模式深度剖析】【7】【行为型】【观察者模式】
👈️上一篇:中介者模式 设计模式-专栏👈️ 文章目录 观察者模式英文原文直译如何理解? 观察者模式的角色类图代码示例 观察者模式的应用观察者模式的优点观察者模式的缺点观察者模式的使用场景 观察者模式 观察者模式(Observer…...

列表的C++实
自动扩容 List item 扩容基数为2 可以设置扩容因子(这里我没有设置) 代码实现如下: // // Created by shaoxinHe on 2024/6/4. //#ifndef CPRIMER_MYLIST_H #define CPRIMER_MYLIST_H#include <stdexcept> #include <vector>namespace st…...

Chisel入门——在windows系统下部署Chisel环境并点亮FPGA小灯等实验
Chisel入门——在windows系统下部署Chisel环境并点亮FPGA小灯等实验 一、chisel简介二、vscode搭建scala开发环境2.1 安装Scala官方插件2.2 java版本(本人用的是jdk18)2.3 下载Scala Windows版本的二进制文件2.4 配置环境变量2.5 scala测试2.6 vscode运行…...

Python和C++赋值共享内存、Python函数传址传值、一些其他的遇到的bug
1、Numpy共享内存的情况: array1 np.array([1, 2, 3]) array2 array1 array2[0] 0 # array1也会跟着改变,就地操作 array2 array2 * 2 # array2不会跟着改变,属于非就地操作,会创建一个新的地址给array2array2 array1…...

深度解析ONLYOFFICE协作空间2.5版本新功能
深度解析ONLYOFFICE协作空间2.5版本新功能 上个月,4月份,ONLYOFFICE协作空间推出了V2.5版本,丰富了一些很实用的新功能,之前已经有文章介绍过了: ONLYOFFICE 协作空间 2.5 现已发布https://blog.csdn.net/m0_6827469…...

Java I/O模型
引言 根据冯.诺依曼结构,计算机结构分为5个部分:运算器、控制器、存储器、输入设备、输出设备。 输入设备和输出设备都属于外部设备。网卡、硬盘这种既可以属于输入设备,也可以属于输出设备。 从计算机结构的视角来看,I/O描述了…...

【简单介绍下Sass,什么是Sass?】
🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…...

bat脚本—快速修改网络配置
一、bat编写前注意事项 windows桌面用文本文件打开把批命令输入在文本框中,保存采用ANSI编码,后缀用.bat 可参考博客——bat脚本简介学习原理以及具体创建方式 (文件扩展名位置) 语法准确性:严格遵循 BAT 脚本的语…...

node.js漏洞——
一.什么是node.js 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 Javascript 的速度非常…...

Qt多线程之moveToThread()函数
文章目录 一、moveToThread()执行后,当前代码线程没有改变。二、对象执行moveToThread()后,哪些成员加入了子线程1、创建对象时不指定父对象2、对属性对象使用moveToThread加入子线程作用域3、将属性对象的创建放到子线程中执行 三、C内存模型 在使用“继…...

【WEB前端2024】智体OS:poplang编程控制成本小千元的长续航robot机器人底盘(开源)
【WEB前端2024】智体OS:poplang编程控制成本小千元的长续航robot机器人底盘(开源) 前言:dtns.network是一款主要由JavaScript编写的智体世界引擎(内嵌了three.js编辑器的定制版-支持以第一视角游览3D场馆)…...

动态规划法学习
当然,让我们用更生活化的语言和一个实际的例子来解释动态规划,以及如何在实践中应用它。 动态规划通俗理解 想象一下,你是个水果摊老板,每天要决定订购多少苹果,目标是最大化利润。但苹果的价格每天波动,…...

前端技术回顾系列 10|TS 泛型在类和接口中的应用
在微信中阅读,关注公众号:CodeFit。 创作不易,如果你觉得这篇文章对您有帮助,请不要忘了 点赞、分享 和 关注 我的公众号:CodeFit,为我的持续创作提供动力。 上文回顾:约束泛型(Generic Constraints) 上一篇文章我们回顾了 泛型 在 TypeScript 中的高级用法 —— 泛型…...

【Ardiuno】实验ESP32单片机自动配置Wifi功能(图文)
这里小飞鱼按照ESP32的示例代码,实验一下wifi的自动配置功能。所谓的自动配置,就是不用提前将wifi的名称和密码写到程序里,这样可以保证程序在烧录上传后,可以通过手机端的软件来进行配置,可以避免反复修改代码&#x…...

xml数据解析
XML Pull Parser(使用Android的XmlPullParser) 原理 Pull Parser允许应用程序代码从XML数据中“拉取”事件,而不是像SAX那样通过事件处理程序被“推送”。应用程序代码可以决定何时拉取下一个事件,如开始元素、结束元素或文本内…...

vite工程化搭建vue项目之自动按需导入
背景 当我们在使用vue3组合式开发的时候,大多数情况下我们的代码可能是这样的 <script setup lang"ts"> import { ref, reactive, toRefs, onMounted, computed } from vue; defineProps({}); </script><template><div></di…...

yolo-inference多后端+多任务+多算法+多精度模型 框架开发记录(python版)
先贴出github地址,欢迎大家批评指正:https://github.com/taifyang/yolo-inference 不知不觉LZ已经快工作两年了,由于之前的工作内容主要和模型部署相关,想着利用闲暇时间写一些推理方面的经验总结,于是有了这个工程。其…...

uniapp使用vue3语法构建自定义导航栏,适配小程序胶囊
具体代码 <template><view class"nav-wrapper-container" :style"height:navBarHeight px"><view class"nav-status-container" :style"height:navstatusBarHeight px;" /><view v-if"isCustom" clas…...

wpf、winform 监听USB拔插时触发
C# USB拔插监听 C#查找设备管理器中所有的 USB 设备 wpf、winform 监听USB拔插时触发 监听Windows USB 拔插时触发 private void MainWindow_Loaded(object sender, RoutedEventArgs e){FleckWebSocketConfig.OpenSocketConfig().GetAwaiter(); //websocket 服务开启用于监听W…...

C语言:指针笔试题
// 输入某一年的第几天,计算并输出它是这一年的第几月第几日。 /* 函数功能: 对给定的某一年的第几天,计算它是这一年的第几月第几日。 函数入口参数: 整形变量year,存储年; 整形变量yearDay,存储某一年的第几天&am…...

搜维尔科技:Movella旗下的Xsens在人形机器人开发中得到广泛应用
人形机器人的发展正在全球范围内受到广泛关注。作为机器人领域的重要分支,人形机器人因其具备高度仿真的外观和动作,以及更贴近人类的行为模式,有望逐渐成为人们日常生活和工业生产中的得力助手。在中国,这一领域的发展尤为引人注…...

k8s学习--kubernetes服务自动伸缩之水平伸缩(pod副本伸缩)HPA详细解释与案例应用
文章目录 前言HPA简介简单理解详细解释HPA 的工作原理监控系统负载模式HPA 的优势使用 HPA 的注意事项应用类型 应用环境1.metircs-server部署2.HPA演示示例(1)部署一个服务(2)创建HPA对象(3)执行压测 前言…...

Mock数据
Mock 数据 引入依赖 <dependency><groupId>com.github.jsonzou</groupId><artifactId>jmockdata</artifactId><version>4.3.0</version></dependency>mock 数据 MockConfig mockConfig new MockConfig().sizeRange(1, 1);A.…...

【MySQL】性能分析
https://www.bilibili.com/video/BV1Kr4y1i7ru/?p78 查看执行频次 查看当前数据库的 INSERT, UPDATE, DELETE, SELECT 访问频次: SHOW GLOBAL STATUS LIKE Com_______; 或者 SHOW SESSION STATUS LIKE Com_______; 慢查询日志 慢查询日志记录了所有执行时间超过指…...

MyBatis插件机制
MyBatis插件机制是该框架提供的一种灵活扩展方式,允许开发者在不修改框架源代码的情况下对MyBatis的功能进行定制和增强。这种机制主要通过拦截器(Interceptor)实现,使得开发者可以拦截和修改MyBatis在执行SQL语句过程中的行为。 …...

NVIDIA Jetson Linux 35.3.1-开发指南-导言
原文地址:Welcome — Jetson Linux Developer Guide documentation (nvidia.com) 欢迎 本开发人员指南适用于 NVIDIA Jetson Linux版本 35.3.1 GA 。 最后更新: 2023年5月19日 NVIDIA Jetson是世界领先的边缘AI平台。其高性能、低功耗计算 深度学习 ,…...

14. fastLED调色板
Color Palettes Functions and class definitions for color palettes.调色板的函数和类定义。 RGB palettes map an 8-bit value (0-255) to an RGB color. You can create any color palette you wish; a couple of starters are provided: ForestColors_p, CloudColors_p…...

bugku---misc---赛博朋克
1、下载附件解压之后是一个txt文本,查看文本的时候看到头部有NG的字样 2、把txt改为png后缀得到一张图片 3、binwalk没发现奇怪的地方,分离出来还是图片 4、stegslove分析,切换图片没有发现奇怪地方 5、将通道rgb置为0。出现了flag但是flag不…...

vue+elementplus模拟“山野愚人居”简单实现个人博客
目录 一、项目介绍 二、项目截图 1.项目结构图 2.项目首页 3.文章详情 4.留言 5.读者 三、源码实现 1.项目依赖package.json 2.项目启动 3.读者页面源码 四、总结 一、项目介绍 模仿原博客:山野愚人居 - 记录我的生活、所见、所闻、所想…… 本项目参考以…...

ComfyUI 完全入门:Refiner精炼器
在 SDXL基础模型1.0版本发布时,Stability AI 公司同时发布了一个名为SDXL Refiner的模型。这个Refiner模型是专门设计用来对基础模型生成的图像进行进一步优化和细化的,所以大家也经常称之为精炼器或者精修器。 Refiner模型的主要目的是提升图像的质量&…...