Python笔记:设计模式之观察者模式
观察者模式中的主题对象一般存在着一个其他服务依赖的核心服务,并且维护着其他依赖此核心服务的对象列表(即观察者或监视者列表),当主题对象发生变化时,观察者应该改变自己的状态或者进行某些操作
观察者模式中的三个角色:
- 主题:即观察者观察的对象,一般是需要有注册和注销方法,用来添加观察者和删除观察者。
- 观察者基类:这个类主要是需要定义一个接口,以便主题发生变化时可以得到对应的通知信息。
- 观察者:这个类需要具体实现基类中的“通知”接口,以便和主题的变化保持同步。
主题的两种通知方式:
- 拉模型:这个方式重心在观察者上,当主题发生变化时,会广播所有的观察者,然后由观察者来获取相应的数据。
- 推模型:这个方式重心在主题上,当主题发生变化时,主题将根据观察者的需要将自身的变化推送给需要的观察者。
观察者模式的优点:
- 观察者模式中彼此交互的对象都是保持松耦合的。主题对观察者唯一的了解就是观察者实现的“通知”接口,除此之外它们之间都是互不影响且独立存在的,可以根据需要对自身作出修改。
- 可以随时添加或删除观察者。
- 这种模式下,可以在很少甚至不修改主题或观察者的情况下进行对象之间高效的数据发送。
其他注意点:
- 观察者模式中是可以有多个主题和多个观察者之间的对应关系的,但是一定要弄清楚它们之间的关系以及变化,不然就会变得非常复杂。
- 一般情况是由主题来触发“通知”方法的,但是在特殊情况下也可以由观察者来触发“通知”方法。
简单示例:
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实现设计模式]-4.观察者模式-吃食啦!
观察者模式是一个非常重要的设计模式. 我们先从一个故事引入. 工作日的每天5点左右,大燕同学都会给大家订饭. 然后7点左右,饭来了. 于是燕哥大吼一声,“饭来啦!”,5点钟定过饭的同学就会纷纷涌入餐厅 ...
- python笔记 - day8
python笔记 - day8 参考: http://www.cnblogs.com/wupeiqi/p/4766801.html http://www.cnblogs.com/wupeiqi/art ...
- [转]Python与设计模式
一.创建类设计模式 前言 什么样的程序员是一个好的程序员?学会很多门编程语言,就是一个好的程序员了么?事实上,学会一门编程语言不是一件很难的事,而“学会”一门编程语言是非常难的一件事.前一个“会”强调 ...
- Python笔记之不可不练
如果您已经有了一定的Python编程基础,那么本文就是为您的编程能力锦上添花,如果您刚刚开始对Python有一点点兴趣,不怕,Python的重点基础知识已经总结在博文<Python笔记之不可不知 ...
- boost.python笔记
boost.python笔记 标签: boost.python,python, C++ 简介 Boost.python是什么? 它是boost库的一部分,随boost一起安装,用来实现C++和Pyth ...
- 20.Python笔记之SqlAlchemy使用
Date:2016-03-27 Title:20.Python笔记之SqlAlchemy使用 Tags:python Category:Python 作者:刘耀 博客:www.liuyao.me 一. ...
- Python笔记——类定义
Python笔记——类定义 一.类定义: class <类名>: <语句> 类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性 如果直接使用类名修改其属 ...
- 13.python笔记之pyyaml模块
Date:2016-03-25 Title:13.Python笔记之Pyymal模块使用 Tags:Python Category:Python 博客地址:www.liuyao.me 作者:刘耀 YA ...
- 8.python笔记之面向对象基础
title: 8.Python笔记之面向对象基础 date: 2016-02-21 15:10:35 tags: Python categories: Python --- 面向对象思维导图 (来自1 ...
- python笔记 - day7-1 之面向对象编程
python笔记 - day7-1 之面向对象编程 什么时候用面向对象: 多个函数的参数相同: 当某一些函数具有相同参数时,可以使用面向对象的方式,将参数值一次性的封装到对象,以后去对象中取值即可: ...
随机推荐
- Centos 7 下安装 Jenkins
Jenkins介绍 Jenkins是一个开源的支持自动化构建.部署等任务的平台.基本上可以说是持续集成(CI).持续发布(CD)不可或缺的工具. 安装Java环境 CentOS 7 安装 JAVA环境 ...
- 在Asp.Net或.Net Core中配置使用MarkDown富文本编辑器有开源模板代码(代码是.net core3.0版本)
研究如何使用Markdown你们可能要花好几天才能搞定,但是看我的文章或者下载了源码,你搞定一般在10分钟之内.我先给各位介绍下它: Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯 ...
- C#_服务器EXCEL模板文件导出
A-1:EXCEL模板导出 非常简单,将EXCEL模板上传到项目中后,将其浏览URL保存下来(excelUrl),然后: window.location.href="http://local ...
- js基本操作
js操作页面三步骤 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...
- 【C++常用函数】头文件<algorithm>中的常用函数(绝对值,交换,比较)
swap(a,b) 用于交换a,b两个变量的值: max(a,b) 返回a,b中的最大值: min(a,b) 返回a,b中的最小值: abs(x) 返回x的绝对值,x必须是整数:
- 易优CMS:if的基础用法
[基础用法] 名称:if 功能:条件判断,比switch判断标签更灵活些,视个人习惯而用. 语法: {eyou:if condition='($eyou.field.has_children > ...
- 关于vue-detools chorme创建安装完成,但是控制台不显示问题
搜了一下发现挺多人遇到这个问题的,绝大多数的回答都是在main.js中添加下面代码 Vue.config.devtools = true; 但是发现并不行. 后来看到有人说刷新然后在按F12就好了,居 ...
- Linux 释放cache
sysc 将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node.已延迟的块 I/O 和读写映射文件 echo 3 > /proc/sys/vm/drop_caches To free p ...
- JS For
JS For 循环可以将代码块执行指定的次数. JavaScript 循环 document.write(cars[0] + "<br>"); document.wri ...
- Linux相关集合
本篇概述 Linux xshell6 连接 Hadoop 启动关闭 Linux xshell6 连接相关问题 首先,虚拟机 得先能通成网(具体教程可百度) 然后,进行 本机 ip 的查询(xshell ...