设计模式Python版 观察者模式
文章目录
- 前言
- 一、观察者模式
- 二、观察者模式示例
前言
GOF设计模式分三大类:
- 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
- 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
- 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。
一、观察者模式
观察者模式(Observer Pattern)
-
定义:定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
-
解决问题:如何实现对象之间一对多的联动?
-
使用场景:
- 一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将发生改变,也不知道这些对象是谁。
- 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……
-
组成:
- Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时定义了通知方法notify()
- ConcreteSubject(具体目标):具体目标是目标类的子类,通常包含有经常发生改变的数据。当它的状态发生改变时,向其各个观察者发出通知。
- Observer(观察者):观察者将对观察目标的改变做出反应。观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。
- ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
-
补充说明:
- 一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,它们之间将产生联动,正所谓“触一而牵百发”。
- 在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者。
- 一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。
- 观察者模式是一种使用频率非常高的设计模式
-
优点:
- 观察者模式可以实现表示层和数据逻辑层的分离。
- 观察者模式在观察目标和观察者之间建立一个抽象的耦合。
- 观察者模式支持广播通信。
- 观察者模式满足开闭原则的要求,增加新的具体观察者无须修改原有系统代码。
-
缺点:
- 将所有的观察者都通知到会花费很多时间
- 如果在观察者和观察目标之间存在循环依赖,可能导致系统崩溃
- 仅仅只是知道观察目标发生了变化,但不知道具体变化

二、观察者模式示例
使用观察者模式来进行多人联机对战游戏的设计
- 多个玩家可以加入同一战队组成联盟,当战队中某一成员受到敌人攻击时将给所有其他盟友发送通知,盟友收到通知后将做出响应。
- AllyControlCenter充当目标类,ConcreteAllyControlCenter充当具体目标类,Observer充当抽象观察者,Player充当具体观察者。
- 实现了两次对象之间的联动:当一个游戏玩家Player对象的beAttacked()方法被调用时,将调用AllyControlCenter的notifyObserver()方法来进行处理,而在notifyObserver()方法中又将调用其他Player对象的help()方法。
- Player.beAttacked() → AllyControlCenter.notifyObserver() → Player.help()
"""观察者模式"""### 目标类class AllyControlCenter:"""战队控制中心"""def __init__(self, ally_name):self.ally_name = ally_name # 战队名称self.players: list[Observer] = [] # 用于存储战队成员def join(self, obs: "Observer"):"""注册方法"""print(f"{obs.name} 加入 {self.ally_name} 战队!")self.players.append(obs)def quit(self, obs: "Observer"):"""注销方法"""print(f"{obs.name} 退出 {self.ally_name} 战队!")self.players.remove(obs)def notify_observer(self, name: str):"""通知方法"""raise NotImplementedError### 具体目标类class ConcreteAllyControlCenter(AllyControlCenter):"""具体战队控制中心"""def __init__(self, ally_name):super().__init__(ally_name)print(f"{self.ally_name} 战队组建成功!")print("#" * 10)def notify_observer(self, name):print(f"{self.ally_name} 战队紧急通知,盟友 {name} 遭受敌人攻击!")# 遍历调用每一个盟友(自己除外)的支援方法for obs in self.players:if obs.name != name:obs.help()### 抽象观察者class Observer:def __init__(self, name):self.name = namedef help(self):"""支援盟友方法"""raise NotImplementedErrordef be_attacked(self, acc: AllyControlCenter):"""遭受攻击方法"""raise NotImplementedError### 具体观察者class Player(Observer):"""战队成员"""def help(self):print(f"坚持住,{self.name} 来支援你!")def be_attacked(self, acc):"""当遭受攻击时将调用战队控制中心类的通知方法来通知盟友"""print(f"{self.name} 被攻击!")acc.notify_observer(self.name)
- 客户端代码
if __name__ == "__main__":acc = ConcreteAllyControlCenter("金陵十二钗")player1 = Player("林黛玉")acc.join(player1)player2 = Player("薛宝钗")acc.join(player2)player3 = Player("贾元春")acc.join(player3)player4 = Player("贾探春")acc.join(player4)player1.be_attacked(acc)
- 输出结果
金陵十二钗 战队组建成功!
##########
林黛玉 加入 金陵十二钗 战队!
薛宝钗 加入 金陵十二钗 战队!
贾元春 加入 金陵十二钗 战队!
贾探春 加入 金陵十二钗 战队!
林黛玉 被攻击!
金陵十二钗 战队紧急通知,盟友 林黛玉 遭受敌人攻击!
坚持住,薛宝钗 来支援你!
坚持住,贾元春 来支援你!
坚持住,贾探春 来支援你!
您正在阅读的是《设计模式Python版》专栏!关注不迷路~
相关文章:
设计模式Python版 观察者模式
文章目录 前言一、观察者模式二、观察者模式示例 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式:关注类和对象之间的组…...
如何在Python用Plot画出一个简单的机器人模型
如何在Python中使用 Plot 画出一个简单的模型 在下面的程序中,首先要知道机器人的DH参数,然后计算出每一个关节的位置,最后利用 plot 函数画出关节之间的连杆就可以了,最后利用 animation 库来实现一个动画效果。 import matplo…...
如何使用ArcGIS Pro制作横向图例:详细步骤与实践指南
ArcGIS Pro,作为Esri公司推出的新一代地理信息系统(GIS)平台,以其强大的功能和灵活的操作界面,在地理数据处理、地图制作和空间分析等领域发挥着重要作用。 在地图制作过程中,图例作为地图的重要组成部分&…...
MySQL 创建指定IP用户并赋予全部权限(兼容8.0以下及8.0以上版本)
在MySQL中,为用户指定访问IP并授予权限是常见的运维操作。但由于MySQL 8.0对用户创建和权限管理机制进行了升级,不同版本的操作存在差异。以下是针对MySQL 8.0以下版本和8.0及以上版本的具体实现方法。 一、MySQL 8.0以下版本(如5.7、5.6) 在MySQL 8.0之前,可以通过一条G…...
每日十个计算机专有名词 (7)
Metasploit 词源:Meta(超越,超出) exploit(漏洞利用) Metasploit 是一个安全测试框架,用来帮助安全专家(也叫渗透测试人员)发现和利用计算机系统中的漏洞。你可以把它想…...
【Python 数据结构 3.顺序表】
目录 一、顺序表基本概念 1.顺序表的概念 2.顺序表的元素插入 元素插入的步骤 3.顺序表的元素删除 元素删除的步骤 4.顺序表的元素查找 元素查找的步骤 5.顺序表的元素索引 元素索引的步骤 6.顺序表的元素修改 元素修改的步骤 二、Python中的顺序表 1.顺序表的定义 2.顺序表的插…...
C# 装箱(Boxing)与拆箱(Unboxing)
C# 装箱(Boxing)与拆箱(Unboxing) 在 C# 中,装箱和拆箱是与值类型(如结构体)和引用类型(如类)之间的转换相关的操作。它们是类型系统的一部分,但如果不正确使…...
[ComfyUI][AI生图]如何在Comfyui中安装插件管理器
如何在ComfyUI便携版中安装插件管理器 在现代软件环境中,图形用户界面(GUI)提供了一种直观的方式来与应用程序交互。ComfyUI是一个出色的GUI框架,它使用户能够通过图形化方式配置和管理他们的应用程序。特别是ComfyUI的便携版,它允许用户在没有安装的情况下使用这一工具,…...
从零开始构建高效Spring Boot应用:实战案例与最佳实践
摘要 本文旨在为初学者及有一定基础的开发者提供一份详尽的指南,以帮助大家深入理解并掌握如何使用Spring Boot框架来快速开发企业级应用程序。通过实际案例分析、代码示例以及架构设计思路分享,读者不仅能够学习到理论知识,还能获得宝贵的实…...
EdgeNext模型详解及代码复现
架构特点 EdgeNeXt是一种集CNN与Transformer于一体的混合架构,其核心创新在于引入了 分割深度转置注意力(SDTA)编码器 。这种设计巧妙地将深度卷积与自适应核大小以及转置注意力相结合,实现了最佳的精度-速度平衡。 SDTA编码器主要由两个组件构成: 特征编码模块 :受Res…...
SQL经典题型
查询不在表里的数据,一张学生表,一张学生的选课表,要求查出没有选课的学生? select students.student_name from students left join course_selection on students.student_idcourse_selection.student_id where course_selecti…...
物联网小范围高精度GPS使用
在园区内实现小范围高精度GPS(全球定位系统)定位,通常需要结合多种技术来弥补传统GPS在精度和覆盖范围上的不足。以下是实现小范围高精度GPS定位的解决方案,包括技术选择、系统设计和应用场景。 一、技术选择 在园区内实现高精度…...
【deepseek第二课】docker部署dify,配置私有化知识库,解决网络超时,成功安装
【deepseek第二课】docker部署dify,配置私有化知识库,解决网络超时,成功安装 1. dify安装1.1 官网安装文档介绍1.2 安装报错,网络连接问题使用镜像加速器处理1.3 dify后台启动很多docker进程 2. 页面探索2.1 设置管理账号2.2 添加…...
P8651 [蓝桥杯 2017 省 B] 日期问题--注意日期问题中2月的天数 / if是否应该连用
P8651 [P8651 [蓝桥杯 2017 省 B] 日期问题--注意日期问题中2月的天数 / if是否应该连用 题目 分析代码 题目 分析 代码中巧妙的用到3重循环,完美的解决了输出的顺序问题【题目要求从小到大】 需要注意的是2月的值,在不同的年份中应该更新2月的值 还有…...
动态规划多阶段报童模型,c++ 实现, java 实现
借助 chaptgpt 和 deepseek,成功实现了c上的多阶段报童模型的动态规划。花费了几天,将以前的 java 程序用 c 实现。 文章目录 C 代码Java 代码 总结: c 还是比 java 快点,30个阶段快了零点几秒c 使用了 unordered_map ࿰…...
hivePB级迁移方案
1、评估磁盘空间大小、调整副本数、设置heapsize大小 2、distcp -i -skipcrccheck 源端到目标端,迁移 3、元数据迁移,建表,替换location地址,或者导出db 4、表分区修复 5、配置增量T-1迁移或者T-2 6、校验历史分区脚本&#…...
Transformer 代码剖析2 - 模型训练 (pytorch实现)
一、模型初始化模块 参考:项目代码 1.1 参数统计函数 def count_parameters(model):return sum(p.numel() for p in model.parameters() if p.requires_grad)#mermaid-svg-OL9twT8AmPz3Bp0O {font-family:"trebuchet ms",verdana,arial,sans-serif;fon…...
PE文件结构详解(DOS头/NT头/节表/导入表)使用010 Editor手动解析notepad++.exe的PE结构
一:DOS部分 DOS部分分为DOS MZ文件头和DOS块,其中DOS MZ头实际是一个64位的IMAGE_DOS——HEADER结构体。 DOS MZ头部结构体的内容如下,我们所需要关注的是前面两个字节(e_magic)和后面四个字节(e_lfanew&a…...
[含文档+PPT+源码等]精品基于Python实现的vue3+Django计算机课程资源平台
基于Python实现的Vue3Django计算机课程资源平台的背景,可以从以下几个方面进行阐述: 一、教育行业发展背景 1. 教育资源数字化趋势 随着信息技术的快速发展,教育资源的数字化已成为不可逆转的趋势。计算机课程资源作为教育领域的重要组成部…...
vue3中ref和reactive响应式数据、ref模板引用(组合式和选项式区别)、组件ref的使用
目录 Ⅰ.ref 1.基本用法:ref响应式数据 2.ref模板引用 3.ref在v-for中的模板引用 4.ref在组件上使用 5.TS中ref数据标注类型 Ⅱ.reactive 1.基本用法:reactive响应式数据 2.TS中reactive标注类型 Ⅲ.ref和reactive的使用场景和区别 Ⅳ.小结…...
Oracle VM VirtualBox 7.1 安装与虚拟机创建全流程指南(Windows平台)
一、软件定位与核心功能 Oracle VM VirtualBox 是开源跨平台虚拟化工具,支持在 Windows、Linux、macOS 系统上创建和管理虚拟机(VM),其核心功能包括: 多系统兼容:可安装 Windows、Ubuntu、CentOS 等 50 操…...
细说 Java GC 垃圾收集器
一、GC目标 业务角度,我们需要追求2个指标: 低延迟(Latency):请求必须多少毫秒内完成响应;高吞吐(Throughput):每秒完成多少次事务。 两者通常存在权衡关系࿰…...
云原生网络篇——万级节点服务网格与智能流量治理
引言:网络即神经系统 2023年双十一期间,某电商平台的支付网关因瞬时流量激增导致服务网格控制面崩溃,造成2.7亿元交易失败。而另一家跨国流媒体公司通过智能流量治理系统,在跨三大洲的云环境中实现了200万QPS的稳定传输。这两个案…...
请解释 React 中的 Hooks,何时使用 Hooks 更合适?
一、Hooks 核心理解 1. 什么是 Hooks? Hooks 是 React 16.8 引入的函数式编程范式,允许在函数组件中使用状态管理和生命周期能力。就像给函数组件装上了"智能芯片",让原本只能做简单展示的组件具备了处理复杂逻辑的能力。 2. 类…...
《国密算法开发实战:从合规落地到性能优化》
前言 随着信息技术的飞速发展,信息安全已成为全球关注的焦点。在数字化时代,数据的保密性、完整性和可用性直接关系到国家、企业和个人的利益。为了保障信息安全,密码技术作为核心支撑,发挥着至关重要的作用。国密算法,即国家密码算法,是我国自主设计和推广的一系列密码…...
第2章 windows故障排除(网络安全防御实战--蓝军武器库)
网络安全防御实战--蓝军武器库是2020年出版的,已经过去3年时间了,最近利用闲暇时间,抓紧吸收,总的来说,第2章开始带你入门了,这里给出了几个windows重要的工具,说实话,好多我也是第一…...
DifyでOracle Base Database Service(23ai)を利用する設定手順
[TOC](DifyでOracle Base Database Service(23ai)を利用する設定手順) はじめに 本記事では、DifyプラットフォームとOracle Base Database Service(23aiエディション)を連携させる方法を解説します。クラウド環境における大規模データ処理を想定した設…...
量子关联特性的多维度探索:五量子比特星型系统与两量子比特系统的对比分析
模拟一个五量子比特系统,其中四个量子比特(编号为1, 2, 3, 4)分别与第五个量子比特(编号为5)耦合,形成一个星型结构。分析量子比特1和2的纠缠熵随时间的变化。 系统的哈密顿量H描述了量子比特间的相互作用…...
初识C语言之操作符详解(上)
一.操作符分类 1.算数操作符: - * / % 2.移位操作符:<< >> 3.位操作符:& | ʌ 4.赋值操作符: - * / % << >> & | ʌ 5.单目操作符࿱…...
HarmonyOS学习第12天:解锁表格布局的奥秘
表格布局初相识 不知不觉,我们在 HarmonyOS 的学习旅程中已经走到了第 12 天。在之前的学习里,我们逐步掌握了 HarmonyOS 开发的各种基础与核心技能,比如组件的基本使用、布局的初步搭建等,这些知识就像一块块基石,为我…...
