当前位置: 首页 > 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. 二叉树中序遍历...

Wan2.2-I2V-A14B镜像优化特性:GPU算力专属调度策略技术白皮书

Wan2.2-I2V-A14B镜像优化特性&#xff1a;GPU算力专属调度策略技术白皮书 1. 镜像概述与核心价值 Wan2.2-I2V-A14B私有部署镜像是一款专为文生视频任务优化的高性能解决方案&#xff0c;针对RTX 4090D 24GB显存显卡进行了深度适配。本镜像开箱即用&#xff0c;内置完整运行环…...

Qwen3.5-9B-GGUF效果实测:混合注意力架构下代码生成准确率提升案例

Qwen3.5-9B-GGUF效果实测&#xff1a;混合注意力架构下代码生成准确率提升案例 1. 模型概述与技术亮点 Qwen3.5-9B-GGUF是基于阿里云开源的Qwen3.5-9B模型经过GGUF格式量化后的版本。这个90亿参数的稠密模型采用了创新的Gated Delta Networks架构&#xff0c;结合了75%线性注…...

如何高效地阅读技术文档?

如何高效地阅读技术文档&#xff1f; 技术文档是开发者日常工作中不可或缺的资源&#xff0c;但面对冗长复杂的文档&#xff0c;许多人常常感到无从下手。高效阅读技术文档不仅能节省时间&#xff0c;还能快速解决问题。那么&#xff0c;如何提升阅读效率呢&#xff1f;以下从…...

AutoJS无限制版安装使用教程:附送礼物与私信自动化脚本完整源码分享

AutoJS无限制版安装使用教程:附送礼物与私信自动化脚本完整源码分享 作为一名每天都在各种APP里“摸鱼”的打工人,我最近发现那些重复性的点击操作简直是在浪费生命。比如刷直播间、自动领福利、或者是给喜欢的博主发私信,点多了手都酸。 为了彻底解放双手,我研究了一下 A…...

Keras实现Mask R-CNN目标检测与实例分割实战

1. 基于Keras的Mask R-CNN目标检测实战指南在计算机视觉领域&#xff0c;目标检测一直是最具挑战性的任务之一。它不仅需要识别图像中的物体是什么&#xff08;分类&#xff09;&#xff0c;还需要精确确定它们的位置&#xff08;定位&#xff09;。作为一名长期从事计算机视觉…...

Parlant:构建可控AI对话智能体的上下文工程与动态匹配框架

1. 项目概述&#xff1a;为什么我们需要一个对话控制层&#xff1f;如果你正在构建面向真实客户的AI智能体&#xff0c;无论是客服、销售还是顾问&#xff0c;你大概率已经踩过这两个坑&#xff1a;要么是系统提示词&#xff08;System Prompt&#xff09;越来越长&#xff0c;…...

MTConnect C++ Agent部署与配置实战:工业数据采集核心组件详解

1. 项目概述&#xff1a;一个工业数据“翻译官”的自我修养 如果你在制造业、工业自动化或者工业物联网&#xff08;IIoT&#xff09;领域摸爬滚打过&#xff0c;肯定遇到过这样的场景&#xff1a;车间里那几台宝贝机床&#xff0c;一台是德国的&#xff0c;一台是日本的&…...

OMC - 09 oh-my-claudecode 的多 Agent 编排实战

文章目录Pre一、问题背景&#xff1a;为什么需要“团队流水线编排”二、总体架构&#xff1a;两条运行时、一个调度内核2.1 双运行时&#xff1a;V1 Watchdog 与 V2 Event-Driven2.2 上层抽象&#xff1a;Skill 层与统一接口三、分阶段流水线&#xff1a;从“先干活”到“先规划…...

别再只加-fPIC了!深入理解静态库、共享库与位置无关代码(PIC)的底层原理与选择策略

深入解析静态库与共享库中的位置无关代码机制 在C/C开发中&#xff0c;我们经常遇到需要将静态库链接到共享库的情况&#xff0c;这时编译器可能会抛出"dangerous relocation: unsupported relocation"的错误。大多数开发者会条件反射地加上-fPIC选项重新编译&#x…...

ncmdump终极指南:快速免费解密网易云NCM音乐格式

ncmdump终极指南&#xff1a;快速免费解密网易云NCM音乐格式 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾经在网易云音乐下载了喜欢的歌曲&#xff0c;却发现只能在特定平台播放&#xff1f;当你尝试在其他设备或播放器上…...