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

python设计模式11:观察者模式

观察者模式

单个对此(发布者,也称为主体或是可观察对象)和一个或是多个对象(订阅者,也称为观察者)之间的发布-订阅关系。增加发布者和订阅这个之间解耦,使得在运行时添加、删除订阅者变得容易。对于MVC, 发布者是模型,订阅者是视图。

拍卖场景:

每个竞买人,都有一个号码牌,当天安门想要出价时,就举起号码牌。当竞买人举起牌子时,拍卖人即为主体,更新竞买价格,并将新价格广播给所有竞买人(竞买者)。

软件场景: 

RabbitMQ  库可以用于应用程序添加异步消息支持,支持多种消息协议,http和amqp 。RbbitMQ 可以在Python 应用与发布订阅模式,该模式就是观察者设计模式。

新闻流: 

使用RSS 、Atom 或其他相关格式。可以关注一个新闻流,每次更新时候,你都会收到一个关于更新的通知。

事件驱动系统

监听器监听特定的事件,监听器在监听的事件被创建时触发。这个事件可以是按下一个特定的键,移动鼠标,事件扮演发布者的角色,监听器扮演观察者的角色。可以为单个事件(发布者)添加多个监听器(观察者)。

案例

格式化程序,有一个默认的格式化程序,以十进制格式显示一个值,可以添加、注册更多的格式化程序。每次更新默认的格式化程序时候,都会通知已经注册的格式化程序采取行动。程序以相关格式显示新的值。

(1) 定义 Publisher 类。

(2) 定义 DefaultFormatter 类,以及特殊的 __init__ 和 __str__ 方法。

(3) 向 DefaultFormatter 类添加 data 属性的设置方法和获取方法。

(4) 定义两个观察者类

(5) 添加程序的主体部分。 main() 函数的第一部分如下。

class Publisher:def __init__(self):self.observers = []  # 保存观察者def add(self, observer):if observer not in self.observers:self.observers.append(observer)else:print(f'Failed to add:{observer}')def remove(self, observer):try:self.observers.remove(observer)except ValueError:print(f"Failed to remove:{observer}")def notify(self):print("所有观察者通知更新")[o.notify(self) for o in self.observers]class DefaultFormatter(Publisher):def __init__(self, name):Publisher.__init__(self)self.name = nameself._data = 0def __str__(self):return f"{type(self).__name__}:'{self.name}' has data ={self._data}"@propertydef data(self):return self._data@data.setterdef data(self, new_value):try:self._data = int(new_value)except ValueError as e:print(f"Error:{e}")else:self.notify()  # 执行通知
"""
定义两个观察者
"""class HexFormatterObs:def notify(self, publisher):value = hex(publisher.data)print(f"{type(self).__name__}: '{publisher.data}' has now hex data ={value}")class BinaryFormatterObs:def notify(self, publisher):value = bin(publisher.data)print(f"{type(self).__name__}:'{publisher.data}' has  now bin data ={value}")def main():df=DefaultFormatter('test1')print(df)print("---------------------")hf=HexFormatterObs()df.add(hf)df.data=3print(df)bf=BinaryFormatterObs()df.add(bf)df.data=21print(df)print("----------hello-----------")df.data='hello'print(df)print("----------15.8-----------")df.data=15.8print(df)
if __name__ == '__main__':main()# try:#     print("33333")# except:#     print("wwww")# else:#     print("else")

执行结果 

DefaultFormatter:'test1' has data =0
---------------------
所有观察者通知更新
HexFormatterObs: '3' has now hex data =0x3
DefaultFormatter:'test1' has data =3
所有观察者通知更新
HexFormatterObs: '21' has now hex data =0x15
BinaryFormatterObs:'21' has  now bin data =0b10101
DefaultFormatter:'test1' has data =21
----------hello-----------
Error:invalid literal for int() with base 10: 'hello'
DefaultFormatter:'test1' has data =21
----------15.8-----------
所有观察者通知更新
HexFormatterObs: '15' has now hex data =0xf
BinaryFormatterObs:'15' has  now bin data =0b1111
DefaultFormatter:'test1' has data =15

http://www.lryc.cn/news/220545.html

相关文章:

  • STM32 GPIO 描述
  • lerna在项目中使用
  • java智能在线考试系统源码 基于SpringBoot+Vue开发
  • 防逆流系统中防逆流电表的正确安装位置-安科瑞黄安南
  • Hello Qt!
  • pytorch加载的cifar10数据集,到底有没有经过归一化
  • Day1 ARM基础
  • ns3入门基础教程
  • 计算机视觉
  • NSSCTF第10页(3)
  • MySQL性能分析工具的使用
  • Uniapp使用AES128加解密16进制
  • C++基础——类与对象
  • 人工智能-卷积神经网络
  • MySQL的event的使用方法
  • Leetcode Daily Challenge 1845. Seat Reservation Manager
  • Blender vs 3ds Max:谁才是3D软件的未来
  • MapReduce:大数据处理的范式
  • 【已解决】ModuleNotFoundError: No module named ‘dgl‘
  • R 复习 菜鸟教程
  • 第十二章《搞懂算法:朴素贝叶斯是怎么回事》笔记
  • 【从0到1开发一个网关】网关Mock功能的实现
  • 前端框架Vue学习 ——(三)Vue生命周期
  • 相机滤镜软件Nevercenter CameraBag Photo mac中文版特点介绍
  • 游戏专用....
  • 第三方登录和第三方支付
  • SpringMvc执行流程(含过滤器Filter+拦截器interceptor)
  • 【UDS基础】简单介绍“统一诊断服务“
  • 深度学习框架TensorFlow.NET之数据类型及张量2(C#)
  • Pandas指定多列组合形成新列