Python笔记之观察者模式


Posted in Python onNovember 20, 2019

观察者模式中的主题对象一般存在着一个其他服务依赖的核心服务,并且维护着其他依赖此核心服务的对象列表(即观察者或监视者列表),当主题对象发生变化时,观察者应该改变自己的状态或者进行某些操作

观察者模式中的三个角色:

  • 主题:即观察者观察的对象,一般是需要有注册和注销方法,用来添加观察者和删除观察者。
  • 观察者基类:这个类主要是需要定义一个接口,以便主题发生变化时可以得到对应的通知信息。
  • 观察者:这个类需要具体实现基类中的“通知”接口,以便和主题的变化保持同步。

主题的两种通知方式:

  • 拉模型:这个方式重心在观察者上,当主题发生变化时,会广播所有的观察者,然后由观察者来获取相应的数据。
  • 推模型:这个方式重心在主题上,当主题发生变化时,主题将根据观察者的需要将自身的变化推送给需要的观察者。

观察者模式的优点:

  • 观察者模式中彼此交互的对象都是保持松耦合的。主题对观察者唯一的了解就是观察者实现的“通知”接口,除此之外它们之间都是互不影响且独立存在的,可以根据需要对自身作出修改。
  • 可以随时添加或删除观察者。
  • 这种模式下,可以在很少甚至不修改主题或观察者的情况下进行对象之间高效的数据发送。

其他注意点:

  • 观察者模式中是可以有多个主题和多个观察者之间的对应关系的,但是一定要弄清楚它们之间的关系以及变化,不然就会变得非常复杂。
  • 一般情况是由主题来触发“通知”方法的,但是在特殊情况下也可以由观察者来触发“通知”方法。

简单示例:

from abc import ABCMeta, abstractmethod


class Publisher:
  """被观察者:发布/订阅关系中的发布对象"""
  def __init__(self):
    self.subscribers = []
    self.latest_content = None

  def set_content(self, content):
    """有新消息时,发布新的消息"""
    self.latest_content = content
    self.publish()

  def get_latest_content(self):
    """获取最新的消息"""
    return self.latest_content

  def register(self, subscriber):
    """注册一个新的订阅者"""
    self.subscribers.append(subscriber)

  def publish(self):
    """发布消息并通知订阅的用户"""
    for subscriber in self.subscribers:
      subscriber.notify()


class Subscriber(metaclass=ABCMeta):
  """观察者的抽象类:需要定义一个通知接口,用于发布对象通知订阅的用户"""
  @abstractmethod
  def notify(self):
    pass


class SubscriberA(Subscriber):
  """观察者A:发布/订阅关系中的订阅者,当订阅的发布者有新的变化或动态的时候能及时收到通知"""
  def __init__(self):
    self.my_publisher = None

  def subscribe(self, publisher):
    """订阅并进行注册"""
    self.my_publisher = publisher
    self.my_publisher.register(self)

  def notify(self):
    """获取最新消息"""
    latest_content = self.my_publisher.get_latest_content()
    print(self, latest_content)


class SubscriberB(Subscriber):
  """观察者B:发布/订阅关系中的订阅者,当订阅的发布者有新的变化或动态的时候能及时收到通知"""
  def __init__(self):
    self.my_publisher = None

  def subscribe(self, publisher):
    """订阅并进行注册"""
    self.my_publisher = publisher
    self.my_publisher.register(self)

  def notify(self):
    """获取最新消息"""
    latest_content = self.my_publisher.get_latest_content()
    print(self, latest_content)


if __name__ == '__main__':
  new_publisher = Publisher()
  subscriber_a = SubscriberA()
  subscriber_a.subscribe(new_publisher)
  subscriber_b = SubscriberB()
  subscriber_b.subscribe(new_publisher)
  new_publisher.set_content('This is a new message!')

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python enumerate函数的使用方法总结
Nov 15 Python
python抓取网页中链接的静态图片
Jan 29 Python
python 从文件夹抽取图片另存的方法
Dec 04 Python
对python中的argv和argc使用详解
Dec 15 Python
对python模块中多个类的用法详解
Jan 10 Python
Python Opencv实现图像轮廓识别功能
Mar 23 Python
python打印9宫格、25宫格等奇数格 满足横竖斜相加和相等
Jul 19 Python
django admin.py 外键,反向查询的实例
Jul 26 Python
python 定时器每天就执行一次的实现代码
Aug 14 Python
Jupyter 无法下载文件夹如何实现曲线救国
Apr 22 Python
jupyter notebook 实现matplotlib图动态刷新
Apr 22 Python
Python开发之QT解决无边框界面拖动卡屏问题(附带源码)
May 27 Python
django 实现celery动态设置周期任务执行时间
Nov 19 #Python
python调用接口的4种方式代码实例
Nov 19 #Python
Python Django2.0集成Celery4.1教程
Nov 19 #Python
通过celery异步处理一个查询任务的完整代码
Nov 19 #Python
Django 自动生成api接口文档教程
Nov 19 #Python
wxpython实现按钮切换界面的方法
Nov 19 #Python
Python性能分析工具Profile使用实例
Nov 19 #Python
You might like
天津市收音机工业发展史
2021/03/04 无线电
超级24小时弹窗代码 24小时退出弹窗代码 100%弹窗代码(IE only)
2010/06/11 Javascript
jquery 获取自定义属性(attr和prop)的实现代码
2012/06/27 Javascript
jquery实现点击其他区域时隐藏下拉div和遮罩层的方法
2015/12/23 Javascript
javascript中call apply 与 bind方法详解
2016/03/10 Javascript
jquery自定义插件——window的实现【示例代码】
2016/05/06 Javascript
AngularJS 前台分页实现的示例代码
2018/06/07 Javascript
JavaScript实现图片懒加载的方法分析
2018/07/05 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
vue-router 中 meta的用法详解
2019/11/01 Javascript
jsonp格式前端发送和后台接受写法的代码详解
2019/11/07 Javascript
Python开发的单词频率统计工具wordsworth使用方法
2014/06/25 Python
win10下Python3.6安装、配置以及pip安装包教程
2017/10/01 Python
python中set()函数简介及实例解析
2018/01/09 Python
PyQt5实现简易计算器
2020/05/30 Python
opencv实现简单人脸识别
2021/02/19 Python
详解Python中的分支和循环结构
2020/02/11 Python
jupyter notebook读取/导出文件/图片实例
2020/04/16 Python
完美解决ARIMA模型中plot_acf画不出图的问题
2020/06/04 Python
Python 没有main函数的原因
2020/07/10 Python
利用CSS3参考手册和CSS3代码生成工具加速来学习网页制
2012/07/11 HTML / CSS
HTML5的新特性(1)
2016/03/03 HTML / CSS
Html5让容器充满屏幕高度或自适应剩余高度的布局实现
2020/05/14 HTML / CSS
英国高端食品和葡萄酒超市:Waitrose
2016/08/23 全球购物
捷克电器和DJ设备网上商店:Electronic-star
2017/07/18 全球购物
Baracuta官方网站:Harrington夹克,G9,G4,G10等
2018/03/06 全球购物
Hanro官网:奢华男士和女士内衣、睡衣和家居服
2018/10/25 全球购物
教育孩子心得体会
2014/01/01 职场文书
高二物理教学反思
2014/02/08 职场文书
大三学年自我鉴定范文(3篇)
2014/09/28 职场文书
致800米运动员广播稿(10篇)
2014/10/17 职场文书
公司承诺函范文
2015/01/21 职场文书
小兵张嘎观后感300字
2015/06/03 职场文书
导游词之潮音寺
2019/09/26 职场文书
Python+Tkinter打造签名设计工具
2022/04/01 Python
解决spring.thymeleaf.cache=false不起作用的问题
2022/06/10 Java/Android