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

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

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

主题的两种通知方式:

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

观察者模式的优点:

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

其他注意点:

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

简单示例:

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笔记:设计模式之观察者模式的更多相关文章

  1. [python实现设计模式]-4.观察者模式-吃食啦!

    观察者模式是一个非常重要的设计模式. 我们先从一个故事引入. 工作日的每天5点左右,大燕同学都会给大家订饭. 然后7点左右,饭来了. 于是燕哥大吼一声,“饭来啦!”,5点钟定过饭的同学就会纷纷涌入餐厅 ...

  2. python笔记 - day8

    python笔记 - day8 参考: http://www.cnblogs.com/wupeiqi/p/4766801.html http://www.cnblogs.com/wupeiqi/art ...

  3. [转]Python与设计模式

    一.创建类设计模式 前言 什么样的程序员是一个好的程序员?学会很多门编程语言,就是一个好的程序员了么?事实上,学会一门编程语言不是一件很难的事,而“学会”一门编程语言是非常难的一件事.前一个“会”强调 ...

  4. Python笔记之不可不练

    如果您已经有了一定的Python编程基础,那么本文就是为您的编程能力锦上添花,如果您刚刚开始对Python有一点点兴趣,不怕,Python的重点基础知识已经总结在博文<Python笔记之不可不知 ...

  5. boost.python笔记

    boost.python笔记 标签: boost.python,python, C++ 简介 Boost.python是什么? 它是boost库的一部分,随boost一起安装,用来实现C++和Pyth ...

  6. 20.Python笔记之SqlAlchemy使用

    Date:2016-03-27 Title:20.Python笔记之SqlAlchemy使用 Tags:python Category:Python 作者:刘耀 博客:www.liuyao.me 一. ...

  7. Python笔记——类定义

    Python笔记——类定义 一.类定义: class <类名>: <语句> 类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性 如果直接使用类名修改其属 ...

  8. 13.python笔记之pyyaml模块

    Date:2016-03-25 Title:13.Python笔记之Pyymal模块使用 Tags:Python Category:Python 博客地址:www.liuyao.me 作者:刘耀 YA ...

  9. 8.python笔记之面向对象基础

    title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...

  10. python笔记 - day7-1 之面向对象编程

    python笔记 - day7-1 之面向对象编程 什么时候用面向对象: 多个函数的参数相同: 当某一些函数具有相同参数时,可以使用面向对象的方式,将参数值一次性的封装到对象,以后去对象中取值即可: ...

随机推荐

  1. leetcode-二叉树

    树以及常用的算法 树的概念 树(Tree)的基本概念树是由结点或顶点和边组成的(可能是非线性的)且不存在着任何环的一种数据结构.没有结点的树称为空(null或empty)树.一棵非空的树包括一个根结点 ...

  2. 前端深入之js篇丨Array数组操作从入门到成神Up Up Up,持续更新中

    写在前面 随着前端深入的不断学习,发现数组这个数据结构在前端中有着相当大的存在感,由于我初学前端的时候并没有系统性的学习数组,所以我将通过这篇文章同你一起学习数组,希望我们能一起进步,学会熟练操作数组 ...

  3. 关于hover与after,before已及first-letter,first-line的联用

    0920自我总结 关于hover与after,before已及first-letter,first-line的联用 一.写法 元素:hover::after{样式} 元素:hover::before{ ...

  4. SSH框架之Struts2第一篇

    1.2 Struts2的概述 : Struts2是一个基于MVC设计模式的WEB层的框架. 1.2.1 常见web层框架 Struts1,Struts2,WebWork,SpringMVC Strut ...

  5. 企业架构如何实施的简介(TOGAF深度好文)

    本文来自企业架构学院: BangEA:如何实施企业架构? IT不仅是开展业务的手段,而且正在迅速演变为业务,IT绩效会直接影响企业的盈利能力,但很多企业并没有适时或充分的让IT组织参与业务的规划和决策 ...

  6. 微信小程序 wxml 文件中如何让多余文本省略号显示?

    废话不多说,之前写小程序碰到了一个问题,如何在 wxml 页面中截取数据? 1.wxs   取数据想必大家都会,不就是 substring 吗?但是这种方法在 wxml 页面中是无效的. 那还有 cs ...

  7. HTTPS请求处理

    HTTPS请求的时候: [1]证书是受信任的,什么都不用做 [2]证书是不受信任的,是自签名的 (1)修改配置文件,禁用ATS特性 (2)信任并安装数字证书 NSURLSession的示例代码如下: ...

  8. bay——RAC 表空间时数据文件误放置到本地文件系统-介质恢复.txt

    RAC添加新表空间时数据文件误放置到本地文件系统的修正 于是我想11G 也兼容这些操作的方法,但是11G的新特性有一点就是可以直接支持ASM文件系统直接可以和本地文件系统进行文件的拷贝了,也就是有三种 ...

  9. linux相关(一)

    一.调整xshell终端显示的最大行数 1.文件 -> 属性 -> 终端,如下图 2.调整缓冲区大小的行数,确定即可,如下图: 注意:此方法只是修改了连接该主机时的显示行数,其他主机的还是 ...

  10. ORA-12505

    tomcat 连不上 oracle,报: java.sql.SQLException: Listener refused the connection with the following error ...