python 设计模式 观察者_设计模式Python实现-观察者模式

观察者模式(发布-订阅模式 Publish Subscribe Pattern):定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者,是它们能够自动更新自己,是一种行为设计模式。

观察者模式的结构

1,Publisher 会向其他对象发送值得关注的事件notifySubscribers。事件会在发布者自身状态改变或执行特定行为后发生。发布者中包含一个允许新订阅者加入subscribe和当前订阅者离开列表unsubscribe的订阅构架。

2,当新事件发生时,发送者会遍历订阅列表并调用每个订阅者对象的通知方法。该方法是在订阅者接口中声明的。

3,Subscriber 接口声明了通知接口。在绝大多数情况下,该接口仅包含一个update方法。该方法可以拥有多个参数,使发布者能在更新时传递事件的详细信息。

4,Concrete Subscriber 具体订阅者,可以执行一些操作来回应发布者的通知。所有具体订阅者类都实现了同样的接口,发布者不与具体类相耦合。

5,订阅者通常需要一些上下文信息来正确地处理更新。因此,发布者通常会将一些上下文数据作为通知方法的参数进行传递。发布者也可将自身作为参数进行传递,使订阅者直接获取所需的数据。

6,Client 会分别创建发布者和订阅者对象,然后为订阅者注册发布者更新。

观察者代码

1 from __future__ importannotations2 from abc importABC, abstractmethod3 from random importrandrange4 from typing importList5

6

7 classSubject(ABC):8 """

9 声明一组用于管理订阅者的方法10 """

11

12 @abstractmethod13 def attach(self, observer: Observer) ->None:14 """

15 添加观察者到subject.16 """

17 pass

18

19 @abstractmethod20 def detach(self, observer: Observer) ->None:21 """

22 从subject删除观察者.23 """

24 pass

25

26 @abstractmethod27 def notify(self) ->None:28 """

29 通知观察者事件的发生.30 """

31 pass

32

33

34 classConcreteSubject(Subject):35 """

36 Subject有一些状态,状态变更需要通知观察者37 """

38 #Subject的状态,所有的订阅者都要有,

39 _state: int =None40

41 #订阅用户列表

42 _observers: List[Observer] =[]43

44 def attach(self, observer: Observer) ->None:45 print("Subject: Attached an observer.")46 self._observers.append(observer)47

48 def detach(self, observer: Observer) ->None:49 self._observers.remove(observer)50

51 #通知所有订阅者

52 def notify(self) ->None:53 """

54 通知接口,触发了所有的订阅用户的update方法55 """

56

57 print("Subject: Notifying observers...")58 for observer inself._observers:59 observer.update(self)60

61 def some_business_logic(self) ->None:62 """

63 一些业务逻辑块,处理业务逻辑后,也可能会触发状态的变更,需要调用notify通知所有订阅者,64 """

65

66 print("\nSubject: state change")67 self._state = randrange(0, 10)68

69 print(f"Subject: My state has changed to: {self._state}")70 self.notify()71

72

73 classObserver(ABC):74 """

75 订阅者声明对象使用的update.76 """

77

78 @abstractmethod79 def update(self, subject: Subject) ->None:80 """

81 接收到状态变更.82 """

83 pass

84

85

86 """

87 具体订阅者,对状态的变更做出具体反应88 """

89

90

91 classConcreteObserverA(Observer):92 def update(self, subject: Subject) ->None:93 if subject._state < 3:94 print("ConcreteObserverA: Reacted to the event")95

96

97 classConcreteObserverB(Observer):98 def update(self, subject: Subject) ->None:99 if subject._state == 0 or subject._state >= 2:100 print("ConcreteObserverB: Reacted to the event")101

102

103 if __name__ == "__main__":104 #The client code.

105

106 subject =ConcreteSubject()107

108 observer_a =ConcreteObserverA()109 subject.attach(observer_a)110

111 observer_b =ConcreteObserverB()112 subject.attach(observer_b)113

114 subject.some_business_logic()115 subject.some_business_logic()116

117 subject.detach(observer_a)118

119 subject.some_business_logic()

适用场景:

1,当一个对象状态的改变需要改变其他对象,或实际对象是事先未知的或动态变化的时,可使用观察者模式。

2,当应用中的一些对象必须观察其他对象时,可使用该模式。

优点:

符合开闭原则,不用修改发布者代码就能引入新的订阅者类。

可以在运行时建立对象之间的联系。

缺点:

订阅者的通知顺序是随机的

作者:Andy

出处:http://www.cnblogs.com/onepiece-andy/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/245862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle loop index,oracle index 聚集因子

简单看一下clustering_factor简单的说CLUSTERING_FACTOR 用于INDEX 的有序度和表的混乱度之间比较b*tree index是经过排序的例如 INDEX中 记录的第一个rowid指向 表所在DATAFILE 中 BLOCK#1 第1行 计数器 记为1&#xff0c;第2个rowid 指向 BLOCK#2 由于改变了块 所以 计数器加…

分析以太网帧结构_传统以太网中的——中继器及集线器

1.1 Repeater 中继器中继器工作在以太网的第一层即物理层&#xff0c; 两端口设备&#xff0c;主要功能是放大信号&#xff0c;从而延长信号在同一网络上传输的长度。中继器的存在主要是解决解决电信号长距离传播过程中的衰减问题&#xff0c;以增加信号强度和传播距离。Figure…

根据oracle入库数据进行告警,Oracle 启动故障案例之--ORA-600 [4193]错误

ORA-600[4193] 这个错误也是与UNDO 有关系&#xff0c;MOS 上有几篇相关的说明文章.一.MOS说明1.1 ORA-600 [4193] WhenTrying To Open The Database [ID 763566.1]SymptomsCopying database from one server to another server and getting an ORA-600 [4193] error when tryi…

html表ge模板_精选甘特图模板,丰富又好用

你听说过甘特图吗&#xff1f;你可能不知道&#xff0c;也有可能是只是听说过但是并不了解。今天我们就来说一说甘特图吧&#xff01;甘特图其实就是是通过标示出活动顺序和时间间隔来表示某一特定项目的顺序与时间之间的关系的一种图表。与时间表或日程规划表不同的部分是甘特…

js函数提示 vscode_为VSCode / Monaco Intellisence添加JavaScript类型提示

有没有办法暗示VSCode / Monaco的intellisense变量的类型.我有一些像这样的代码var loc window.location;var gl context1.getContext("webgl");var ctx context2.getContext("2d");我看到VSCode知道loc是一个URL但它不知道gl是什么它也不知道ctx是什么…

oracle中调试存储过程,详解Oracle调试存储过程

详解Oracle调试存储过程一 调试关键步骤1、在要调试的存储过程右键&#xff0c;选择编辑以进行调试&#xff0c;截图如下&#xff1a;2、点击小瓢虫&#xff0c;弹出调试窗口&#xff0c;截图如下&#xff1a;3、输入7839员工编号&#xff0c;点击确认&#xff0c;进行调试&…

imp oracle full,Oracle 10g imp 之 full database (转官档)

Using Export and Import to Move a DatabaseBetweenPlatforms10g官档:The Export and Import utilities are the only method that Oracle supports for moving an existing Oracle database from one hardware platform. to another. This includes moving between UNIX and …

python朴素贝叶斯对wine_基于朴素贝叶斯对Wine数据集分类

龙源期刊网http://www.qikan.com.cn基于朴素贝叶斯对Wine数据集分类作者&#xff1a;夏赵建杜友福来源&#xff1a;《电脑知识与技术》2017年第29期摘要&#xff1a;为了解决由于葡萄酒的组成成分十分复杂与多样而导致它的类型分类与品质划分困难的问题&#xff0c;减少由于感官…

伪静态php配置,PHP开启伪静态配置

1.检测Apache是否开启mod_rewrite功能可以通过php提供的phpinfo()函数查看环境配置&#xff0c;找到“Loaded Modules”&#xff0c;其中列出了所有apache2handler已经开启的模块&#xff0c;如果里面包括“mod_rewrite”&#xff0c;则已经支持&#xff0c;不再需要继续设置。…

python flask上传文件_Python-Flask-文件上传

一、Python-Flask-文件上传1、简化版文件上传创建目录&#xff1a;cd 5-4mkdir -p uploads #必须先创建uploads文件夹。upload.htmlTitle文件上传示例app.pyimport osfrom flask import Flask, render_template, send_from_directory, request, jsonify, make_responseimport t…

linux的apache安装在哪个目录,在linux系统下apache的默认安装路径在哪

如果采用RPM包安装&#xff0c;安装路径应在 /etc/httpd目录下。(学习教程推荐&#xff1a;apache)apache配置文件&#xff1a;/etc/httpd/conf/httpd.conf 可以修改相关的访问路径及配置Apache模块路径&#xff1a;/usr/sbin/apachectl 启动模块web目录&#xff1a;/var/www/h…

车子Linux系统,Linux车载系统Automotive Grade Linux

【中关村在线软件资讯】7月8日消息&#xff1a;Linux在车载系统上&#xff0c;并不想落后于苹果、谷歌等竞争对手&#xff0c;这不&#xff0c;Linux最近也推出了可定制的车载系统平台——Automotive Grade Linux&#xff0c;旨在建立一个未来智能汽车系统的标准。Linux车载系统…

linux 进程带宽限制,在Linux中限制网络带宽使用

限制网络流量速率的一种方法是通过一个名为trickle的命令行工具。通过在程序运行时&#xff0c;预先加载一个速率限制 socket 库 的方法&#xff0c;trickle 命令允许你改变任意一个特定程序的流量。 trickle 命令有一个很好的特性是它仅在用户空间中运行&#xff0c;这意味着&…

gpedit msc组策略面板 win10在哪里_windows10的组策略在哪

展开全部请参看:网页链接第一种方法:无论32位还是64位,均可.我的是64位.How to Enable Group Policy Editor (gpedit.msc) In Windows 10 Home EditionLast Updated on: July 10, 2020 by Usman Khurshid这里下载的就是个批处理文件gpedit-enabler.bat,内容是:echo offpushd &q…

linux ping监控脚本,WINDOWS和LINUX下带时间的PING包监控脚本

WINDOWS使用方法;cscript ping.vbs 172.26.163.10 -t -l 1000Dim args, flag, unsuccOutargs""otherout""flag0If WScript.Arguments.count 0 ThenWScript.Echo "Usage: cscript ping.vbs [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]&q…

nx set 怎么实现的原子性_正确地使用Redis的SETNX实现锁机制

setNX&#xff0c;是set if not exists 的缩写&#xff0c;也就是只有不存在的时候才设置, 设置成功时返回 1 &#xff0c; 设置失败时返回 0 。可以利用它来实现锁的效果&#xff0c;但是很多人在使用的过程中都有一些问题没有考虑到。例如某个查询数据库的接口因为请求量比较…

linux img 内核启动,linux的启动流程(initrd.img)

http://www.ibm.com/developerworks/cn/linux/l-initrd.html一、从哪里到哪里本文旨在描述linux中内核如何调用启动&#xff0c;然后如何从img的文件系统切换到硬盘的过程。描述起于&#xff1a;linux-2.6.11/init/main.c中函数 static int init(void * unused)描述止于&#x…

python的flask实现第三方登录怎么写_关于qq和新浪微博的第三方登陆|python|flask

前些日子研究了一下qq和新浪微博的第三方登陆的东西&#xff0c;发现其实难度并不大。来给大家分享一下我的经验和流程。不论是qq还是新浪微博的第三方登陆都是用了Oauth2.0授权流程&#xff0c;唯一不同的是qq多了一个openid的获取&#xff0c;多了一步。先介绍一下Oauth2.0的…

linux boot分区有什么用,/ boot分区的真正作用是什么?

射门很难引导...好吧...这确实是最难的部分。每次启动计算机时&#xff0c;它基本上都会重新适应。它熟悉其各个部分&#xff0c;并且满足每个部分都具有功能。但可以说&#xff0c;它每次都要从自己的引导程序中拉起自己。在设计启动过程时&#xff0c;技巧是逐步启动计算机。…

内存颗粒位宽和容量_64M的SDRAM颗粒 一般内存是多大的?

内存颗粒识别存储颗粒主要有这样的一些品牌&#xff1a;美国的Micron(美光)、德国的Infineon(英飞凌)&#xff1b;韩国的SAMSUNG(三星)、HY(现代)&#xff1b;日本的NEC(日本电气)、Hitachi(日立)、Mitsubishi(三菱)、Toshiba(东芝)&#xff1b;台湾的EilteMT、ESMT(晶豪)、Etr…