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基础教程之缩进介绍
Aug 29 Python
Python字符串处理实例详解
May 18 Python
python生成词云的实现方法(推荐)
Jun 13 Python
python数据结构之列表和元组的详解
Sep 23 Python
python的paramiko模块实现远程控制和传输示例
Oct 13 Python
Python内存管理方式和垃圾回收算法解析
Nov 11 Python
python基于物品协同过滤算法实现代码
May 31 Python
解决Mac下首次安装pycharm无project interpreter的问题
Oct 29 Python
对python numpy.array插入一行或一列的方法详解
Jan 29 Python
Python中请不要再用re.compile了
Jun 30 Python
Django框架视图函数设计示例
Jul 29 Python
python GUI库图形界面开发之PyQt5图片显示控件QPixmap详细使用方法与实例
Feb 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
PHP+SQL 注入攻击的技术实现以及预防办法
2011/01/27 PHP
php中使用sftp教程
2015/03/30 PHP
php通过smtp邮件验证登陆的方法
2016/05/11 PHP
PHP实现微信小程序人脸识别刷脸登录功能
2018/05/24 PHP
laravel框架添加数据,显示数据,返回成功值的方法
2019/10/11 PHP
浅谈laravel框架与thinkPHP框架的区别
2019/10/23 PHP
jQuery获取文本节点之 text()/val()/html() 方法区别
2011/03/01 Javascript
读jQuery之六 缓存数据功能介绍
2011/06/21 Javascript
JQuery中对服务器控件 DropdownList, RadioButtonList, CheckboxList的操作总结
2011/06/28 Javascript
jQuery 在光标定位的地方插入文字的插件
2012/05/10 Javascript
JavaScript面向对象之Prototypes和继承
2012/07/12 Javascript
js获取input标签的输入值实现代码
2013/08/05 Javascript
浅析JavaScript中的同名标识符优先级
2013/12/06 Javascript
javascript实现简单的贪吃蛇游戏
2015/03/31 Javascript
Javascript数组中push方法用法分析
2016/10/31 Javascript
JavaScript实现移动端轮播效果
2017/06/06 Javascript
js排序与重组的实例讲解
2017/08/28 Javascript
Vue.directive 自定义指令的问题小结
2018/03/04 Javascript
vue制作抓娃娃机的示例代码
2020/04/17 Javascript
[01:03:50]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第二场 2月7日
2021/03/11 DOTA
python实现图书借阅系统
2019/02/20 Python
Python中一些深不见底的“坑”
2019/06/12 Python
Python中py文件转换成exe可执行文件的方法
2019/06/14 Python
Python FTP文件定时自动下载实现过程解析
2019/11/12 Python
python实现图片插入文字
2019/11/26 Python
Python安装whl文件过程图解
2020/02/18 Python
Python基于locals返回作用域字典
2020/10/17 Python
纯CSS实现聊天框小尖角、气泡效果
2014/04/04 HTML / CSS
新西兰便宜隐形眼镜购买网站:QUICKLENS New Zealand
2019/03/02 全球购物
医学检验专业个人求职信范文
2013/12/04 职场文书
成功的酒店创业计划书
2013/12/27 职场文书
药剂专业自荐信范文
2014/04/16 职场文书
社会学专业求职信
2014/07/17 职场文书
行政主管岗位职责范本
2015/04/09 职场文书
大客户经理岗位职责
2015/04/09 职场文书
MySQL中几种插入和批量语句实例详解
2021/09/14 MySQL