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多线程下载文件的方法
Jul 10 Python
Python中几种导入模块的方式总结
Apr 27 Python
python实现简单http服务器功能
Sep 17 Python
python统计中文字符数量的两种方法
Jan 31 Python
Python动态参数/命名空间/函数嵌套/global和nonlocal
May 29 Python
Python爬虫图片懒加载技术 selenium和PhantomJS解析
Sep 18 Python
详解Django CAS 解决方案
Oct 30 Python
pytorch实现mnist分类的示例讲解
Jan 10 Python
django models里数据表插入数据id自增操作
Jul 15 Python
利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
Nov 01 Python
Python实战之实现康威生命游戏
Apr 26 Python
Python编解码问题及文本文件处理方法详解
Jun 20 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设计模式 Template (模板模式)
2011/06/26 PHP
php header功能的使用
2013/10/28 PHP
PHP封装的XML简单操作类完整实例
2017/11/13 PHP
textarea的value是html文件源代码,存成html文件的代码
2007/04/20 Javascript
cookie在javascript中的使用技巧以及隐私在服务器端的设置
2012/12/03 Javascript
js function定义函数的几种不错方法
2014/02/27 Javascript
JQuery为页面Dom元素绑定事件及解除绑定方法
2014/04/23 Javascript
浅谈JavaScript函数的四种存在形态
2016/06/08 Javascript
JS获取年月日时分秒的方法分析
2016/11/28 Javascript
Bootstrap基本样式学习笔记之按钮(4)
2016/12/07 Javascript
实现一个简单的vue无限加载指令方法
2017/01/10 Javascript
最常见和最有用的字符串相关的方法详解
2017/02/06 Javascript
Angular2中如何使用ngx-translate进行国际化
2017/05/21 Javascript
nodejs集成sqlite使用示例
2017/06/05 NodeJs
NodeJs通过async/await处理异步的方法
2017/10/09 NodeJs
JS编写兼容IE6,7,8浏览器无缝自动轮播
2018/10/12 Javascript
BootStrap模态框闪退问题实例代码详解
2018/12/10 Javascript
自定义Vue中的v-module双向绑定的实现
2019/04/17 Javascript
重置Redux的状态数据的方法实现
2019/11/18 Javascript
Vue中import from的来源及省略后缀与加载文件夹问题
2020/02/09 Javascript
vue 在单页面应用里使用二级套嵌路由
2020/12/19 Vue.js
用Python的Django框架来制作一个RSS阅读器
2015/07/22 Python
详解Python中正则匹配TAB及空格的小技巧
2019/07/26 Python
Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
2019/10/12 Python
python多进程下的生产者和消费者模型
2020/05/07 Python
使用Keras加载含有自定义层或函数的模型操作
2020/06/10 Python
python中判断数字是否为质数的实例讲解
2020/12/06 Python
python 基于selectors库实现文件上传与下载
2020/12/31 Python
英国领先的NHS批准的在线药店:Pharmacy2U
2017/01/06 全球购物
俄罗斯美容和健康网上商店:Созвездие Красоты
2019/07/23 全球购物
C#怎么让一个窗口居中显示?
2015/10/20 面试题
校运会广播稿100字
2014/01/27 职场文书
六查六看六改心得体会
2014/10/14 职场文书
初中优秀学生评语
2014/12/29 职场文书
学生保证书格式
2015/02/27 职场文书
导游词之开封禹王台风景区
2019/12/02 职场文书