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 变量类型及命名规则介绍
Jun 08 Python
python实现猜数字游戏(无重复数字)示例分享
Mar 29 Python
Python程序设计入门(1)基本语法简介
Jun 13 Python
以windows service方式运行Python程序的方法
Jun 03 Python
使用Python写个小监控
Jan 27 Python
Python处理文本文件中控制字符的方法
Feb 07 Python
浅析Python 实现一个自动化翻译和替换的工具
Apr 14 Python
手把手教你使用Python创建微信机器人
Apr 29 Python
Python numpy线性代数用法实例解析
Nov 15 Python
Python 简单计算要求形状面积的实例
Jan 18 Python
在Tensorflow中查看权重的实现
Jan 24 Python
python 非线性规划方式(scipy.optimize.minimize)
Feb 11 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表单敏感字符过滤类
2014/12/08 PHP
PHP读取大文件的多种方法介绍
2016/04/04 PHP
PHP下用Swoole实现Actor并发模型的方法
2019/06/12 PHP
laravel框架数据库配置及操作数据库示例
2019/10/10 PHP
地址栏上的一段语句,改变页面的风格。(教程)
2008/04/02 Javascript
js判断上传文件的类型和大小示例代码
2013/10/18 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
2014/05/22 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
解析JavaScript的ES6版本中的解构赋值
2015/07/28 Javascript
JavaScript实现快速排序的方法
2015/07/31 Javascript
jquery实现的简单二级菜单效果代码
2015/09/22 Javascript
JS中正则表达式只有3种匹配模式(没有单行模式)详解
2016/07/28 Javascript
Bootstrap Navbar Component实现响应式导航
2016/10/08 Javascript
微信小程序 wxapp导航 navigator详解
2016/10/31 Javascript
解析js如何获取css样式
2016/12/11 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
2017/03/08 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
JavaScript格式化json和xml的方法示例
2019/01/22 Javascript
python中使用pyhook实现键盘监控的例子
2014/07/18 Python
python的多重继承的理解
2017/08/06 Python
Python中Threading用法详解
2017/12/27 Python
python删除服务器文件代码示例
2018/02/09 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
基于OpenCV python3实现证件照换背景的方法
2019/03/22 Python
摩顿布朗英国官方网上商店:奢华沐浴、身体和头发护理
2016/10/29 全球购物
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
阿联酋网上花店:Ferns N Petals
2018/02/14 全球购物
Farfetch中文官网:奢侈品牌时尚购物平台
2020/03/15 全球购物
灵泰克Java笔试题
2016/01/09 面试题
马云的职业生涯规划之路
2014/01/01 职场文书
毕业生就业协议书
2014/04/11 职场文书
2014年最新离婚协议书范本
2014/10/11 职场文书
初三学生语文考试作弊检讨书
2014/12/14 职场文书
2015年安全生产管理工作总结
2015/05/25 职场文书
2016年社区六一儿童节活动总结
2016/04/06 职场文书
SqlServer 垂直分表(减少程序改动)
2021/04/16 SQL Server