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 13 Python
Django实现简单分页功能的方法详解
Dec 05 Python
Python将多个excel表格合并为一个表格
Feb 22 Python
Python实现针对给定字符串寻找最长非重复子串的方法
Apr 21 Python
PyTorch CNN实战之MNIST手写数字识别示例
May 29 Python
Python将字符串常量转化为变量方法总结
Mar 17 Python
django rest framework serializer返回时间自动格式化方法
Mar 31 Python
pycharm解决关闭flask后依旧可以访问服务的问题
Apr 03 Python
Python多线程threading创建及使用方法解析
Jun 17 Python
Python logging模块进行封装实现原理解析
Aug 07 Python
Python基础之数据结构详解
Apr 28 Python
Elasticsearch 聚合查询和排序
Apr 19 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类
2006/07/15 PHP
浅谈PHP检查数组中是否存在某个值 in_array 函数
2016/06/13 PHP
php 防止表单重复提交两种实现方法
2016/11/03 PHP
php中strtotime函数性能分析
2016/11/20 PHP
PHP DB 数据库连接类定义与用法示例
2019/03/11 PHP
新浪刚打开页面出来的全屏广告代码
2007/04/02 Javascript
Ext 今日学习总结
2010/09/19 Javascript
JS仿flash上传头像效果实现代码
2011/07/18 Javascript
AngularJS入门教程(零):引导程序
2014/12/06 Javascript
JS获取数组最大值、最小值及长度的方法
2015/11/24 Javascript
express文件上传中间件Multer详解
2016/10/24 Javascript
JavaScript设计模式之代理模式详解
2017/06/09 Javascript
详解JavaScript中操作符和表达式
2018/09/12 Javascript
JS判断用户用的哪个浏览器实例详解
2018/10/09 Javascript
PHPStorm中如何对nodejs项目进行单元测试详解
2019/02/28 NodeJs
nodejs脚本centos开机启动实操方法
2020/03/04 NodeJs
浅谈JavaScript 声明提升
2020/09/14 Javascript
[07:09]2014DOTA2国际邀请赛-Newbee再次发威成功晋级决赛
2014/07/19 DOTA
Python中关于Sequence切片的下标问题详解
2017/06/15 Python
Python中的self用法详解
2019/08/06 Python
使用python实现kNN分类算法
2019/10/16 Python
Python如何通过百度翻译API实现翻译功能
2020/04/02 Python
UI自动化定位常用实现方法代码示例
2020/10/27 Python
python实现马丁策略回测3000只股票的实例代码
2021/01/22 Python
python 实现IP子网计算
2021/02/18 Python
HTML5本地存储之Database Storage应用介绍
2013/01/06 HTML / CSS
H5 video poster属性设置视频封面的方法
2020/05/25 HTML / CSS
银行门卫岗位职责
2013/12/29 职场文书
优秀教师获奖感言
2014/01/31 职场文书
小学体育教学反思
2014/01/31 职场文书
房地产项目策划书
2014/02/05 职场文书
秋天的怀念教学反思
2014/04/28 职场文书
优秀管理者事迹材料
2014/05/22 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
离婚案件上诉状
2015/05/23 职场文书
2016年11月份红领巾广播稿
2015/12/21 职场文书