Python笔记之观察者模式

所属分类: 脚本专栏 / python 阅读数: 2004
收藏 0 赞 0 分享

观察者模式中的主题对象一般存在着一个其他服务依赖的核心服务,并且维护着其他依赖此核心服务的对象列表(即观察者或监视者列表),当主题对象发生变化时,观察者应该改变自己的状态或者进行某些操作

观察者模式中的三个角色:

  • 主题:即观察者观察的对象,一般是需要有注册和注销方法,用来添加观察者和删除观察者。
  • 观察者基类:这个类主要是需要定义一个接口,以便主题发生变化时可以得到对应的通知信息。
  • 观察者:这个类需要具体实现基类中的“通知”接口,以便和主题的变化保持同步。

主题的两种通知方式:

  • 拉模型:这个方式重心在观察者上,当主题发生变化时,会广播所有的观察者,然后由观察者来获取相应的数据。
  • 推模型:这个方式重心在主题上,当主题发生变化时,主题将根据观察者的需要将自身的变化推送给需要的观察者。

观察者模式的优点:

  • 观察者模式中彼此交互的对象都是保持松耦合的。主题对观察者唯一的了解就是观察者实现的“通知”接口,除此之外它们之间都是互不影响且独立存在的,可以根据需要对自身作出修改。
  • 可以随时添加或删除观察者。
  • 这种模式下,可以在很少甚至不修改主题或观察者的情况下进行对象之间高效的数据发送。

其他注意点:

  • 观察者模式中是可以有多个主题和多个观察者之间的对应关系的,但是一定要弄清楚它们之间的关系以及变化,不然就会变得非常复杂。
  • 一般情况是由主题来触发“通知”方法的,但是在特殊情况下也可以由观察者来触发“通知”方法。

简单示例:

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常见加密模块用法分析【MD5,sha,crypt模块】

这篇文章主要介绍了Python常见加密模块用法,结合实例形式较为详细的分析了MD5,sha与crypt模块加密的相关实现方法与操作技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

Python向日志输出中添加上下文信息

这篇文章主要介绍了Python向日志输出中添加上下文信息的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Python实现的简单dns查询功能示例

这篇文章主要介绍了Python实现的简单dns查询功能,结合实例形式分析了Python基于socket模块的dns信息查询实现技巧,需要的朋友可以参考下
收藏 0 赞 0 分享

利用Anaconda完美解决Python 2与python 3的共存问题

Anaconda 是 Python 的一个发行版,如果把 Python 比作 Linux,那么 Anancoda 就是 CentOS 或者 Ubuntu,下面这篇文章主要给大家介绍了利用Anaconda完美解决Python 2与python 3共存问题的相关资料,文中介绍的非常详
收藏 0 赞 0 分享

Python随机读取文件实现实例

这篇文章主要介绍了Python随机读取文件的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

用生成器来改写直接返回列表的函数方法

下面小编就为大家带来一篇用生成器来改写直接返回列表的函数方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

python爬虫入门教程--快速理解HTTP协议(一)

http协议是互联网里面最重要,最基础的协议之一,我们的爬虫需要经常和http协议打交道。下面这篇文章主要给大家介绍了关于python爬虫入门之快速理解HTTP协议的相关资料,文中介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
收藏 0 赞 0 分享

老生常谈Python进阶之装饰器

下面小编就为大家带来一篇老生常谈Python进阶之装饰器。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅谈Python基础之I/O模型

下面小编就为大家带来一篇浅谈Python基础之I/O模型。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

python如何获取服务器硬件信息

这篇文章主要为大家详细介绍了python获取服务器硬件信息的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享
查看更多