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 BeautifulSoup使用方法详解
Nov 21 Python
浅谈Python中的闭包
Jul 08 Python
python各种语言间时间的转化实现代码
Mar 23 Python
Python制作简易注册登录系统
Dec 15 Python
对Python2与Python3中__bool__方法的差异详解
Nov 01 Python
用python打印1~20的整数实例讲解
Jul 01 Python
python实现人工智能Ai抠图功能
Sep 05 Python
详解pyinstaller selenium python3 chrome打包问题
Oct 18 Python
Python递归求出列表(包括列表中的子列表)的最大值实例
Feb 27 Python
解决导入django_filters不成功问题No module named 'django_filter'
Jul 15 Python
python语言实现贪吃蛇游戏
Nov 13 Python
如何用python绘制雷达图
Apr 24 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
MVC模式的PHP实现
2006/10/09 PHP
php关于array_multisort多维数组排序的使用说明
2011/01/04 PHP
php实现微信公众平台账号自定义菜单类
2014/12/02 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
php与python实现的线程池多线程爬虫功能示例
2016/10/12 PHP
因str_replace导致的注入问题总结
2019/08/08 PHP
js call方法详细介绍(js 的继承)
2013/11/18 Javascript
跟我学习javascript的prototype原型和原型链
2015/11/18 Javascript
AngularJS 过滤与排序详解及实例代码
2016/09/14 Javascript
js date 格式化
2017/02/15 Javascript
微信小程序中显示倒计时代码实例
2019/05/09 Javascript
Vue CLI3中使用compass normalize的方法
2019/05/30 Javascript
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
详解Nuxt.js 实战集锦
2019/11/19 Javascript
node 版本切换的实现
2020/02/02 Javascript
微信小程序 bindtap 传参的实例代码
2020/02/21 Javascript
Python及PyCharm下载与安装教程
2017/11/18 Python
使用python生成目录树
2018/03/29 Python
Python(Django)项目与Apache的管理交互的方法
2018/05/16 Python
django输出html内容的实例
2018/05/27 Python
详解Python数据可视化编程 - 词云生成并保存(jieba+WordCloud)
2019/03/26 Python
python 字符串常用函数详解
2019/09/11 Python
基于virtualenv创建python虚拟环境过程图解
2020/03/30 Python
python在一个范围内取随机数的简单实例
2020/08/16 Python
selenium+headless chrome爬虫的实现示例
2021/01/08 Python
施华洛世奇美国官网:SWAROVSKI美国
2018/02/08 全球购物
英国复古和经典球衣网站:Vintage Football Shirts
2018/10/05 全球购物
师范毕业生自荐信
2013/10/17 职场文书
毕业生个人求职的自我评价
2013/10/28 职场文书
违纪检讨书2000字
2014/02/08 职场文书
销售会计岗位职责
2014/03/15 职场文书
奥林匹克的口号
2014/06/13 职场文书
给老婆道歉的话
2015/01/20 职场文书
行为习惯主题班会
2015/08/14 职场文书
应届生个人的求职(自荐信范文2篇)
2019/08/23 职场文书
使用goaccess分析nginx日志的详细方法
2021/07/09 Servers