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

什么是观察者模式?用 Python 如何实现 Observer(观察者或发布订阅)对象行为型模式?

什么是观察者模式?

观察者模式(Observer pattern)是一种行为型设计模式,它允许对象之间建立一种一对多的依赖关系,当一个对象的状态发生变化时,其相关依赖对象都会得到通知并自动更新。

在这里插入图片描述

在观察者模式中,有两个主要角色:观察者(Observers)和被观察者(Subject)。被观察者维护了一个观察者列表,并提供了方法来添加、删除和通知观察者。观察者则定义了一个接口,用于接收被观察者的通知。

观察者模式的核心思想是解耦,被观察者和观察者之间并不直接依赖于彼此,而是通过接口进行交互。这样可以使得它们之间的关系更加灵活和可扩展。

模式的意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

别名

依赖(dependent),发布-订阅(publish-subscribe)

一般步骤:
  1. 定义被观察者接口:被观察者接口定义了添加、删除和通知观察者的方法。

  2. 实现被观察者类:被观察者类实现了被观察者接口,并维护了一个观察者列表。它在状态发生变化时,遍历观察者列表,调用它们的通知方法。

  3. 定义观察者接口:观察者接口定义了接收通知的方法。

  4. 实现观察者类:观察者类实现了观察者接口,并在接收到通知时执行相应的操作。

  5. 创建被观察者对象和观察者对象:在应用程序中创建被观察者对象和观察者对象,并将观察者对象注册到被观察者对象中。

通过观察者模式,可以实现松耦合的对象之间的通信,使得系统更加灵活和可维护。


在 Python 3 中,我们可以使用以下方式实现观察者设计模式

首先,定义一个主题(Subject)类,它负责管理观察者列表、添加观察者、删除观察者以及通知观察者的操作。

class Subject:def __init__(self):self.observers = []def add_observer(self, observer):self.observers.append(observer)def remove_observer(self, observer):self.observers.remove(observer)def notify_observers(self, *args, **kwargs):for observer in self.observers:observer.update(*args, **kwargs)

然后,定义观察者(Observer)类,它包含一个 update() 方法,用于接收主题的通知并执行相应的操作。

class Observer:def update(self, *args, **kwargs):# 执行观察者的操作pass

最后,我们可以创建具体的主题和观察者类,并在需要的地方使用它们。

# 具体主题类
class ConcreteSubject(Subject):def do_something(self):# 做一些操作# 操作完成后通知观察者self.notify_observers(data)# 具体观察者类
class ConcreteObserver(Observer):def update(self, *args, **kwargs):# 接收到主题的通知后执行操作data = kwargs.get('data')# 执行相应的操作

使用时,我们可以创建一个具体主题对象和多个具体观察者对象,并将观察者添加到主题的观察者列表中。然后,当主题发生变化时,调用 notify_observers() 方法通知所有观察者进行更新操作。

subject = ConcreteSubject()
observer1 = ConcreteObserver()
observer2 = ConcreteObserver()subject.add_observer(observer1)
subject.add_observer(observer2)# 主题执行操作并通知观察者进行更新
subject.do_something()  

这样,当主题对象调用 notify_observers() 方法时,所有观察者的 update() 方法将被调用,并可以根据需要执行相应的操作。

以上就是使用 Python 3 实现观察者设计模式的基本步骤。我们可以根据具体的需求进行扩展和调整。


在实现观察者模式时,有一些需要注意的地方:

  1. 观察者的通知顺序:观察者被通知的顺序可能会对系统的行为产生影响。在有些情况下,观察者的通知顺序可能是比较重要的,因此需要仔细考虑和设计观察者的调用顺序。

  2. 避免循环依赖:当观察者和被观察者相互引用时,可能会导致循环依赖的问题。这可能会导致内存泄漏或其他意外行为。要确保在设计中避免循环依赖问题,或者使用弱引用来解决这个问题。

  3. 考虑线程安全性:如果在多线程环境下使用观察者模式,需要考虑线程安全性。确保在对观察者列表进行修改时采取适当的同步措施,以避免竞态条件和数据不一致的问题。

  4. 考虑性能影响:如果观察者模式在大规模的系统中使用,可能会对性能产生影响。当通知大量观察者时,需要注意性能问题,并进行优化。

  5. 避免过度使用观察者模式:观察者模式适用于对象之间的一对多关系,但并不是所有情况下都需要使用观察者模式。在设计中,需要根据实际需求和系统架构来决定是否使用观察者模式,避免过度复杂化系统。

通过注意以上几点,可以更好地应用观察者模式,并确保系统的可靠性和性能。


本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇

相关文章:

什么是观察者模式?用 Python 如何实现 Observer(观察者或发布订阅)对象行为型模式?

什么是观察者模式? 观察者模式(Observer pattern)是一种行为型设计模式,它允许对象之间建立一种一对多的依赖关系,当一个对象的状态发生变化时,其相关依赖对象都会得到通知并自动更新。 在观察者模式中&am…...

pytorch直线拟合

目录 1、数据分析 2、pytorch直线拟合 1、数据分析 直线拟合的前提条件通常包括以下几点: 存在线性关系:这是进行直线拟合的基础,数据点之间应该存在一种线性关系,即数据的分布可以用直线来近似描述。这种线性关系可以是数据点…...

相机传感器

相机的传感器大小通常用英寸(1英寸2.54厘米)来表示。例如:全画幅相机的传感器大小为:36mm*24mm,称为 35mm全画幅。 几分之一英寸 所谓的 1/2.7,1/2.5等等,里面的分子1是一个标准,分…...

大语言模型的关键技术

大语言模型的关键技术: 经过漫长的发展,LLM 进化到了当前的状态——通用且有能力的学习者。在这个过程中,人们提出了许多重要的技术,大大提升了 LLM 的能力。在此,我们简要列举了几种重要的技术,这些技术&a…...

uniapp使用vur-cli新建项目并打包

新建项目 npm install -g vue/cli vue create -p dcloudio/uni-preset-vue my-project选择默认模板npm run dev:h5 运行 安装sass和uview &#xff08;npm安装失败&#xff09; bug&#xff1a;使用uni.scss中的变量或样式&#xff0c;<style lang"scss"> 必…...

后台管理系统解决方案-中大型-Vben Admin

后台管理系统解决方案-中大型-Vben Admin 官网 Vben Admin 在线演示 Vben Admin 为什么选择它 github现有20K星&#xff0c;并且它有个可视化生成表单&#xff0c;我很喜欢 快速开始 # 拉取代码 git clone https://github.com/vbenjs/vue-vben-admin-doc# 安装依赖 yarn#…...

通俗理解repartition和coalesce区别

官方的解释 reparation 返回一个具有恰好numPartitions分区的新RDD。 可以增加或减少此RDD中的并行级别。在内部,reparation会使用shuffle来重新分发的数据。 如果要减少此RDD中的分区数量,请考虑使用coalesce,这样可以避免执行shuffle。 coalesce 返回一个新的RDD,该RDD被…...

优雅设计之美:实现Vue应用程序的时尚布局

本文为翻译文章&#xff0c;原文链接&#xff1a; ** https://fadamakis.com/clean-layout-architecture-for-vue-applications-a738201a2a1e 前言 页面布局是减少代码重复和创建可维护且具有专业外观的应用程序的基本模式。如果使用的是Nuxt&#xff0c;则可以提供开箱即用…...

05预测识别-依托YOLO V8进行训练模型的识别——对视频中的目标进行跟踪统计

上文中详细介绍了如何对视频进行抽帧,并对帧的图像进行目标识别。但在日常工作中,我们也会遇到需要对目标进行跟踪统计的情况,比如我们需要连续统计某一类目标有多少个的时候,如果单纯从帧中抽取图像的话,系统将无法判断是否为同一目标,从而造成目标数量统计的重复,导致…...

Android Studio(意图Intent)

前言 意图的作用&#xff1a;页面的跳转&#xff08;从一个页面跳转到另一个页面&#xff09;。 意图的创建&#xff1a;需要哪些参数&#xff1f;首先&#xff0c;从哪个页面跳转到哪个页面&#xff1b;其二&#xff0c;跳转到另一个页面需要携带数据吗。 下面介绍顺序&#x…...

Bean作用域

从笔者之前的博客&#xff0c;我们可以看出 Spring 是⽤来读取和存储 Bean&#xff0c;因此在 Spring 中 Bean 是最核⼼的操作 资源&#xff0c;所以接下来我们深⼊学习⼀下 Bean 对象&#xff1a;Bean作用域&#xff01; 限定程序中变量的可用范围叫做作用域&#xff01;或者…...

YOLOV5----修改损失函数-SE

主要修改yolo.py、yolov5s.yaml及添加SE.py 一、SE.py import numpy as np import torch from torch import nn from torch.nn import initclass SEAttention(nn.Module):def __init__(self, channel=512...

Mybatis(一)

1. Mybatis简介 MyBatis下载地址 1.1 MyBatis历史 MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投Google Code旗下&#xff0c;iBatis3.x正式更名为MyBatis。代码于2013年11月迁移到Github…...

使用Go构建一个Postgres流平台

使用 Go 通道从拉推模型转向更高效的流方法。这通过重叠拉取和推送阶段来提高性能&#xff0c;减少总体处理时间和延迟。 Go通道提供数据同步、资源管理和并发处理。它们允许 goroutine 安全地通信和交换数据。这些源实现了每秒 10-12k 事务的吞吐量&#xff0c;最小延迟为 1-…...

QT基础与细节理解

前言 本博客旨在记录QT学习过程中的一些细节知识理解&#xff0c;由于问题的产生并非成体系&#xff0c;所以前期的记录可能会无序一些。烦请读者参阅目录进行快速的问题定位与跳转 QT基础与细节理解 前言正文部分QT基础1&#xff1a;正确理解: QWidget(parent), ui(new Ui::u…...

【MySQL数据库】 六

本文主要介绍了数据库原理中数据库索引和事务相关概念. 一.索引 在查询表的时候,最基本的方式就是遍历表,一条一条筛选 . 因此,就可以给这个表建立索引,来提高查找的速度 比如,按照id建立索引 在数据库上额外搞一个空间维护一些id 相关的信息, id:1 表的某个位置 id:2 …...

微信总提示空间不足怎么办?三个方法随心选!

微信显示空间不足会给用户带来很多困扰&#xff0c;比如影响手机的正常使用&#xff0c;占用大量存储空间&#xff0c;导致手机运行缓慢&#xff0c;没法分享图片和视频&#xff0c;影响我们的社交交流。下面提供了一些简单实用的方法。 方法一&#xff1a;清理微信缓存 1、打…...

C语言每日一题(27)链表中倒数第k个结点

牛客网 链表中倒数第k个结点 题目描述 描述 输入一个链表&#xff0c;输出该链表中倒数第k个结点。 思路分析 这是一道经典的快慢指针题&#xff0c;fast和slow最开始都指向头结点&#xff0c;对于输入值k&#xff0c;先让快指针fast先走k步&#xff0c;之后再让两个指针一…...

pdf转word

1、pip install pdf2docx 2、 from pdf2docx import Converterpdf_filerH:\测试.pdf docx_filerH:\测试_word.docxcvConverter(pdf_file) cv.convert(docx_file,start0,endNone) cv.close()会根据H目录中的pdf,在本目录自动生成相应的word...

LeetCode热题100——二叉树

二叉树 1. 二叉树中序遍历 1. 二叉树中序遍历...

基于安卓的社区商铺联盟促销平台毕业设计

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。一、研究目的本研究旨在构建一个基于安卓系统的社区商铺联盟促销平台以解决传统社区商业生态中存在的信息孤岛与资源分散问题。当前城市社区商业发展面临多重挑战&#xff1a…...

基于Java的LangChain4j智能客服实战:从零搭建企业级对话系统

告别“答非所问、越聊越懵”,用Java生态原生的AI框架让客服系统真正“听得懂、记得住、扩得快”。 一、传统客服系统的三大问题 在帮某金融客户做智能客服升级时,我第一次切身体会到传统客服系统的困境。用户问完“我的订单呢?”,紧跟着问“发货了吗?”,机器人却仿佛失忆…...

图像分类中像素缩放算法选择与优化实践

1. 图像分类任务中的像素缩放方法概述在计算机视觉领域&#xff0c;像素缩放是图像预处理环节中最基础却至关重要的步骤。当我们把原始图像输入卷积神经网络(CNN)进行训练或推理时&#xff0c;绝大多数情况下都需要先将图像调整为统一尺寸。这个看似简单的操作&#xff0c;实际…...

VTJ.PRO v2.3.8 版本发布:接入 DeepSeek V4,多项功能升级提升开发者体验

VTJ.PRO v2.3.8 版&#xff1a;多项功能升级亮点多低代码开发平台 VTJ.PRO 正式发布 v2.3.8 版本&#xff0c;此次更新带来了一系列重要能力。在 AI 能力方面&#xff0c;系统提示词更新后支持自主拆分区块组件&#xff0c;可根据页面结构自动将可复用部分抽象为独立组件&#…...

告别零散文件!用Inno Setup一键打包你的Unity游戏(Windows版保姆级教程)

告别零散文件&#xff01;用Inno Setup一键打包你的Unity游戏&#xff08;Windows版保姆级教程&#xff09; 当你终于完成Unity游戏的开发&#xff0c;准备将作品分享给朋友或发布到小型平台时&#xff0c;是否曾为那些散落的.exe、Data文件夹和MonoBleedingEdge文件感到困扰&…...

ReactAgent:基于GPT-4的React组件智能生成器实战解析

1. 项目概述&#xff1a;一个能“听懂”需求的React组件生成器 如果你和我一样&#xff0c;是个常年和React、TypeScript打交道的开发者&#xff0c;那你肯定经历过这样的场景&#xff1a;产品经理或者设计师拿着一个用户故事&#xff08;User Story&#xff09;过来&#xff…...

留学生的“求职时差”陷阱:为什么大二不规划,大四就容易陷入被动?

在留学生的家庭教育规划中&#xff0c;往往存在一个隐蔽且致命的认知偏差&#xff1a;家长普遍认为&#xff0c;只要孩子在海外名校保持优异的 GPA&#xff08;平均绩点&#xff09;&#xff0c;毕业后自然能拿到名企的入场券。而许多学生也习惯性地遵循“大一适应、大二上课、…...

SWE-agent:基于LLM的自主代码修复智能体实战指南

1. 从GitHub问题到自动修复&#xff1a;SWE-agent深度解析与实战 如果你是一名开发者&#xff0c;每天打开GitHub看到待处理的issue列表&#xff0c;是不是偶尔会想&#xff0c;要是能有个“数字实习生”自动把这些bug修了该多好&#xff1f;或者&#xff0c;作为一名安全研究…...

AI教材写作新趋势:低查重AI工具,让教材生成更高效!

教材编写痛点与AI工具的解决方案 教材编写过程中&#xff0c;繁琐的格式要求让不少编者感到苦恼。比如&#xff0c;标题的字体大小该如何选择&#xff1f;参考文献应该遵循GB/T7714还是特定出版标准&#xff1f;习题的排版方式是单栏还是双栏&#xff1f;这些不同的要求让人眼…...

手把手教你用STM32CubeMX配置PWM驱动智能小车:从生成代码到让轮子转起来(STM32F103C8T6+TB6612)

零基础玩转STM32CubeMX&#xff1a;5分钟配置PWM驱动智能小车全攻略 第一次接触STM32开发时&#xff0c;最让我头疼的就是那些密密麻麻的寄存器配置。直到发现了STM32CubeMX这个神器&#xff0c;才真正体会到什么叫"图形化开发"的效率革命。今天就用最接地气的方式&…...