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日志模块logging简介
Apr 13 Python
一个基于flask的web应用诞生(1)
Apr 11 Python
Django 浅谈根据配置生成SQL语句的问题
May 29 Python
Python中栈、队列与优先级队列的实现方法
Jun 30 Python
完美解决pycharm导入自己写的py文件爆红问题
Feb 12 Python
python字符串常用方法及文件简单读写的操作方法
Mar 04 Python
tensorflow实现从.ckpt文件中读取任意变量
May 26 Python
Python实现封装打包自己写的代码,被python import
Jul 12 Python
Python读取Excel一列并计算所有对象出现次数的方法
Sep 04 Python
scrapy利用selenium爬取豆瓣阅读的全步骤
Sep 20 Python
python爬虫使用scrapy注意事项
Nov 23 Python
python四种出行路线规划的实现
Jun 23 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语法(1)
2006/10/09 PHP
Codeigniter生成Excel文档的简单方法
2014/06/12 PHP
php简单复制文件的方法
2016/05/09 PHP
浅析PHP7新功能及语法变化总结
2016/06/17 PHP
jquery中this的使用说明
2010/09/06 Javascript
js输出列表实现代码
2010/09/12 Javascript
理解JAVASCRIPT中hasOwnProperty()的作用
2013/06/05 Javascript
利用JQuery和Servlet实现跨域提交请求示例分享
2014/02/12 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
TinyMCE汉化及本地上传图片功能实例详解
2016/05/31 Javascript
深入理解ECMAScript的几个关键语句
2016/06/01 Javascript
微信公众号 客服接口的开发实例详解
2016/09/28 Javascript
AngularJS指令用法详解
2016/11/02 Javascript
Bootstrap整体框架之JavaScript插件架构
2016/12/15 Javascript
Bootstrap jquery.twbsPagination.js动态页码分页实例代码
2017/02/20 Javascript
Angular在一个页面中使用两个ng-app的方法(二)
2017/02/20 Javascript
还不懂递归?读完这篇文章保证你会懂
2018/07/29 Javascript
浅谈关于iview表单验证的问题
2018/09/29 Javascript
CentOS7中源码编译安装NodeJS的完整步骤
2018/10/13 NodeJs
react同构实践之实现自己的同构模板
2019/03/13 Javascript
React优化子组件render的使用
2019/05/12 Javascript
详解Vue-cli3.X使用px2rem遇到的问题
2019/08/09 Javascript
Vuex的API文档说明详解
2020/02/05 Javascript
在Ubuntu系统下安装使用Python的GUI工具wxPython
2016/02/18 Python
python 实现删除文件或文件夹实例详解
2016/12/04 Python
解决pycharm 工具栏Tool中找不到Run manager.py Task的问题
2019/07/01 Python
Python在Matplotlib图中显示中文字体的操作方法
2019/07/29 Python
浅谈django框架集成swagger以及自定义参数问题
2020/07/07 Python
django rest framework使用django-filter用法
2020/07/15 Python
思想汇报范文
2013/11/04 职场文书
车辆工程专业求职信
2014/04/28 职场文书
战略性融资合作协议书范本
2014/10/17 职场文书
2015年“公民道德宣传日”活动方案
2015/05/06 职场文书
2016秋季运动会前导词
2015/11/25 职场文书
写作技巧:如何撰写一份优秀的营销策划书
2019/08/13 职场文书
springcloud整合seata
2022/05/20 Java/Android