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中 os._exit() 和 sys.exit(), exit(0)和exit(1) 的用法和区别
Jun 23 Python
python+opencv+caffe+摄像头做目标检测的实例代码
Aug 03 Python
Python使用pydub库对mp3与wav格式进行互转的方法
Jan 10 Python
Python3.5运算符操作实例详解
Apr 25 Python
Python 虚拟空间的使用代码详解
Jun 10 Python
python pygame实现挡板弹球游戏
Nov 25 Python
Python基本类型的连接组合和互相转换方式(13种)
Dec 16 Python
Mac中PyCharm配置Anaconda环境的方法
Mar 04 Python
Django model重写save方法及update踩坑详解
Jul 27 Python
Python爬虫之爬取淘女郎照片示例详解
Jul 28 Python
Python爬取12306车次信息代码详解
Aug 12 Python
Python的flask接收前台的ajax的post数据和get数据的方法
Apr 12 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
使用PHP会话(Session)实现用户登陆功能
2013/06/29 PHP
PHP实现上传图片到数据库并显示输出的方法
2018/05/31 PHP
Yii2语言国际化的配置教程
2018/08/19 PHP
laravel添加前台跳转成功页面示例
2019/10/22 PHP
PHP isset empty函数相关面试题及解析
2020/12/11 PHP
测试你的JS的掌握程度的代码
2009/12/09 Javascript
js 遍历对象的属性的代码
2011/12/29 Javascript
js+JQuery返回顶部功能如何实现
2012/12/03 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
jQuery中filter()和find()的区别深入了解
2013/09/25 Javascript
javascript移出节点removeChild()使用介绍
2014/04/03 Javascript
javascript制作的网页侧边弹出框思路及实现代码
2014/05/21 Javascript
jQuery插件扩展extend的简单实现原理
2016/06/24 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
2017/11/27 Javascript
深入浅析Vue.js 中的 v-for 列表渲染指令
2018/11/19 Javascript
vue前后分离调起微信支付
2019/07/29 Javascript
Vue项目中使用better-scroll实现菜单映射功能方法
2019/09/11 Javascript
jQuery实现朋友圈查看图片
2020/09/11 jQuery
Flask框架学习笔记(一)安装篇(windows安装与centos安装)
2014/06/25 Python
python实时获取外部程序输出结果的方法
2019/01/12 Python
PYTHON绘制雷达图代码实例
2019/10/15 Python
win10系统下python3安装及pip换源和使用教程
2020/01/06 Python
20行Python代码实现一款永久免费PDF编辑工具的实现
2020/08/27 Python
matplotlib部件之矩形选区(RectangleSelector)的实现
2021/02/01 Python
美国知名的家庭连锁百货商店:Boscov’s
2017/07/27 全球购物
New Balance澳大利亚官网:运动鞋和健身服装
2019/02/23 全球购物
【魔兽争霸3重制版】原版画面与淬火MOD画面对比
2021/03/26 魔兽争霸
生物医学工程专业学生求职信范文分享
2013/12/14 职场文书
迟到检讨书1000字
2014/01/15 职场文书
护士毕业实习感言
2014/03/05 职场文书
领导干部遵守党的政治纪律情况思想汇报
2014/09/14 职场文书
民主生活会对照检查材料范文
2014/10/01 职场文书
地球一小时活动总结
2015/02/27 职场文书
2015年行风建设工作总结
2015/05/15 职场文书
Pygame Rect区域位置的使用(图文)
2021/11/17 Python
React四级菜单的实现
2022/04/08 Javascript