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随机生成数模块random使用实例
Apr 13 Python
python实现比较两段文本不同之处的方法
May 30 Python
python批量制作雷达图的实现方法
Jul 26 Python
微信跳一跳小游戏python脚本
Jan 05 Python
python+matplotlib实现鼠标移动三角形高亮及索引显示
Jan 15 Python
基于python进行桶排序与基数排序的总结
May 29 Python
django 信号调度机制详解
Jul 19 Python
超简单的Python HTTP服务
Jul 22 Python
vue学习笔记之动态组件和v-once指令简单示例
Feb 29 Python
Python+appium框架原生代码实现App自动化测试详解
Mar 06 Python
Keras设定GPU使用内存大小方式(Tensorflow backend)
May 22 Python
python爬虫用mongodb的理由
Jul 28 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
用文本文件制作留言板提示(下)
2006/10/09 PHP
PHP与SQL注入攻击[二]
2007/04/17 PHP
php和vue配合使用技巧和方法
2019/05/09 PHP
javasript实现密码的隐藏与显示
2015/05/08 Javascript
JavaScript绑定事件监听函数的通用方法
2016/05/14 Javascript
easyui messager alert 三秒后自动关闭提示的实例
2016/11/07 Javascript
详解Angular的内置过滤器和自定义过滤器【推荐】
2016/12/26 Javascript
js实现3D图片环展示效果
2017/03/09 Javascript
VsCode新建VueJs项目的详细步骤
2017/09/23 Javascript
[18:20]DOTA2 HEROS教学视频教你分分钟做大人-昆卡
2014/06/11 DOTA
[51:44]2018DOTA2亚洲邀请赛 4.3 突围赛 Optic vs iG 第二场
2018/04/04 DOTA
python将人民币转换大写的脚本代码
2013/02/10 Python
Python中的包和模块实例
2014/11/22 Python
CentOS安装pillow报错的解决方法
2016/01/27 Python
浅谈pyqt5中信号与槽的认识
2019/02/17 Python
Python3.6实现带有简单界面的有道翻译小程序
2019/04/16 Python
django将网络中的图片,保存成model中的ImageField的实例
2019/08/07 Python
Python使用tkinter模块实现推箱子游戏
2019/10/08 Python
Python.append()与Python.expand()用法详解
2019/12/18 Python
Python3 ffmpeg视频转换工具使用方法解析
2020/08/10 Python
HTML5混合开发二维码扫描以及调用本地摄像头
2017/12/27 HTML / CSS
斯凯奇澳大利亚官网:SKECHERS澳大利亚
2018/03/31 全球购物
Nisbets法国:英国最大的厨房和餐饮设备供应商
2019/03/18 全球购物
中专毕业生自我鉴定
2013/11/21 职场文书
财务会计应届生求职信
2013/11/24 职场文书
实习教师自我鉴定
2013/12/12 职场文书
体育教育专业自荐信范文
2013/12/20 职场文书
我的画教学反思
2014/04/28 职场文书
材料物理专业求职信
2014/09/01 职场文书
优秀党员推荐材料
2014/12/18 职场文书
会计工作态度自我评价
2015/03/06 职场文书
刑事上诉状(无罪)
2015/05/23 职场文书
亮剑观后感600字
2015/06/05 职场文书
2015年董事长秘书工作总结
2015/07/23 职场文书
入党申请书怎么写?
2019/06/21 职场文书
goland 恢复已更改文件的操作
2021/04/28 Golang