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专用方法与迭代机制实例分析
Sep 15 Python
在Django的视图(View)外使用Session的方法
Jul 23 Python
tensorflow学习笔记之mnist的卷积神经网络实例
Apr 15 Python
解决Python下json.loads()中文字符出错的问题
Dec 19 Python
python ChainMap 合并字典的实现步骤
Jun 11 Python
Python简易版图书管理系统
Aug 12 Python
Matplotlib绘制雷达图和三维图的示例代码
Jan 07 Python
pycharm解决关闭flask后依旧可以访问服务的问题
Apr 03 Python
Python字符串函数strip()原理及用法详解
Jul 23 Python
python re.match()用法相关示例
Jan 27 Python
tensorflow2.0教程之Keras快速入门
Feb 20 Python
解决pycharm下载库时出现Failed to install package的问题
Sep 04 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支持多种格式图片上传(支持jpg、png、gif)
2011/11/03 PHP
thinkphp中ajax与php响应过程详解
2014/12/08 PHP
ThinkPHP中url隐藏入口文件后接收alipay传值的方法
2014/12/09 PHP
用php和jQuery来实现“顶”和“踩”的投票功能
2016/10/13 PHP
php5.x禁用eval的操作方法
2018/10/19 PHP
通过Javascript将数据导出到外部Excel文档的函数代码
2012/06/15 Javascript
各种常用的JS函数整理
2013/10/25 Javascript
js的Boolean对象初始值示例
2014/03/04 Javascript
js实现有时间限制消失的图片方法
2015/02/27 Javascript
ES6中的箭头函数实例详解
2017/04/06 Javascript
详解用vue.js和laravel实现微信授权登陆
2017/06/23 Javascript
vue用addRoutes实现动态路由的示例
2017/09/15 Javascript
vue利用axios来完成数据的交互
2018/03/23 Javascript
JS添加或删除HTML dom元素的方法实例分析
2019/03/05 Javascript
详解vue中v-model和v-bind绑定数据的异同
2020/08/10 Javascript
OpenLayers3实现图层控件功能
2020/09/25 Javascript
[01:43]倾听DOTA2英雄之声 魅惑魔女国服配音鉴赏
2013/06/06 DOTA
python 中文乱码问题深入分析
2011/03/13 Python
Python判断直线和矩形是否相交的方法
2015/07/14 Python
Python如何实现MySQL实例初始化详解
2017/11/06 Python
利用Tensorflow的队列多线程读取数据方式
2020/02/05 Python
Python任务调度利器之APScheduler详解
2020/04/02 Python
python数据类型强制转换实例详解
2020/06/22 Python
Pycharm 2020.1 版配置优化的详细教程
2020/08/07 Python
Django 权限管理(permissions)与用户组(group)详解
2020/11/30 Python
10个python爬虫入门基础代码实例 + 1个简单的python爬虫完整实例
2020/12/16 Python
圣诞树世界:Christmas Tree World
2019/12/10 全球购物
车间班长岗位职责
2013/11/30 职场文书
工程业务员岗位职责
2013/12/31 职场文书
生活小常识广播稿
2014/09/16 职场文书
局机关干部群众路线个人对照检查材料思想汇报
2014/10/05 职场文书
学习心理学的体会
2014/11/07 职场文书
2015大学生求职信范文
2015/03/20 职场文书
银行稽核岗位职责
2015/04/13 职场文书
李白经典诗之一:全文无一“月”字,却句句有月
2019/07/12 职场文书
一文搞懂Redis中String数据类型
2022/04/03 Redis