Python设计模式之观察者模式实例


Posted in Python onApril 26, 2014

关于设计模式中的观察者模式,定义如下(维基百科):

?察者模式(有?r又被??榘l布/??模式)是????模式的一?。在此?模式中,一??目?宋锛?芾硭?邢嘁漓端?挠^察者物件,?K且在它本身的??B改??r主?影l出通知。?通常透?呼叫各?察者所提供的方法????。此?模式通常被用???作事件?理系?。
简单来说,一个被观察者有很多观察者,被观察者的状态的改变会引起所有观察者的响应操作。

那么我们用Python2.7来实现观察者模式。

Python中的集合set

集合(set),类似于列表(list),但是它没有重复的元素,它的doc内容如下:

>>> print set.__doc__
set() -> new empty set object
set(iterable) -> new set object
Build an unordered collection of unique elements.

下面是在ipython中进行的几个简单的集合操作。
In [1]: myset = set()
In [2]: myset.add(1)
In [3]: myset.add(2)
In [4]: myset.add('s')
In [5]: print myset
set([1, 2, 's'])
In [6]: myset.add('s')
In [7]: print myset
set([1, 2, 's'])
In [8]: myset.remove(3)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-8-a93073f8a2af> in <module>()
----> 1 myset.remove(3)
KeyError: 3
In [9]: myset.remove(1)
In [10]: print myset
set([2, 's'])

通过内置的set()可以产生一个空的集合对象,也可以在set中传入一些参数,例如一个列表:
>>> print set([1,2,3,3])
set([1, 2, 3])

最常用的方法就是add和remove了,更多内容可以参考http://docs.python.org/2/library/stdtypes.html#set。

一个简单的观察者模式的实现

class Observer(object):
    def __init__(self, s):
        self.s = s
    def update(self):
        print self.s
if __name__ == '__main__':
    foo01 = Observer("hi, i am foo01")
    foo02 = Observer("hi, i am foo02")
    observers = set()
    observers.add(foo01)
    observers.add(foo01)
    observers.add(foo02)
    print observers
    for ob in observers:
        ob.update()

下面是运行结果:
set([<__main__.Observer object at 0xb74627cc>, <__main__.Observer object at 0xb74627ec>])
hi, i am foo01
hi, i am foo02

运行结果中第一行是集合observers的内容,其包含了两个Observer实例,这些实例所处的内存地址在每次运行时可能有不同。而
for ob in observers:
    ob.update()

就可以看成多个观察者产生响应。

当然,这种实现并不好——被观察者也应该是一个实例。

更加完善的观察者模式实现

class ObserverInterface(object):
    def __init__(self):
        pass
    def update(self):
        pass
class SubjectInterface(object):
    def __init__(self):
        self.observers = set()
    def addObserver(self, ob):
        self.observers.add(ob)
    def delObserver(self, ob):
        self.observers.remove(ob)
    def notifyObservers(self):
        for ob in self.observers:
            ob.update()
class Observer01(ObserverInterface):
    def __init__(self, s):
        self.s = s
    def update(self):
        print self.s
class Observer02(ObserverInterface):
    def __init__(self, num1, num2):
        self.num1 = num1
        self.num2 = num2
    def update(self):
        print self.num1 + self.num2
class Subject01(SubjectInterface):
    def __init__(self):
        SubjectInterface.__init__(self)
if __name__ == '__main__':
    ob01 = Observer01("hi, i am ob01")
    ob02 = Observer02("hello,","i am ob02")
    observers = set()
    sb01 = Subject01()
    sb01.addObserver(ob01)
    sb01.addObserver(ob02)
    sb01.notifyObservers()

运行结果如下:
hi, i am ob01
hello,i am ob02
Python 相关文章推荐
使用简单工厂模式来进行Python的设计模式编程
Mar 01 Python
Python学习pygal绘制线图代码分享
Dec 09 Python
深入理解Python爬虫代理池服务
Feb 28 Python
解决pycharm运行时interpreter为空的问题
Oct 29 Python
python实现控制台打印的方法
Jan 12 Python
Python自动化运维之Ansible定义主机与组规则操作详解
Jun 13 Python
解决Keras 与 Tensorflow 版本之间的兼容性问题
Feb 07 Python
python简单的三元一次方程求解实例
Apr 02 Python
python是怎么被发明的
Jun 15 Python
Python基于httpx模块实现发送请求
Jul 07 Python
matplotlib 画双轴子图无法显示x轴的解决方法
Jul 27 Python
python 邮件检测工具mmpi的使用
Jan 04 Python
Python设计模式之代理模式实例
Apr 26 #Python
python中的列表推导浅析
Apr 26 #Python
Python中的Numpy入门教程
Apr 26 #Python
Python中的map、reduce和filter浅析
Apr 26 #Python
Python实现的Kmeans++算法实例
Apr 26 #Python
爬山算法简介和Python实现实例
Apr 26 #Python
Python操作sqlite3快速、安全插入数据(防注入)的实例
Apr 26 #Python
You might like
PHP导出MySQL数据到Excel文件(fputcsv)
2011/07/03 PHP
PHP 读取Postgresql中的数组
2013/04/14 PHP
php单元测试phpunit入门实例教程
2017/11/17 PHP
jquery form表单提交插件asp.net后台中文解码
2010/06/12 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件
2010/08/24 Javascript
jquery实现心算练习代码
2010/12/06 Javascript
常用一些Javascript判断函数
2012/08/14 Javascript
JS根据年月获得当月天数的实现代码
2014/07/03 Javascript
浅谈JavaScript Math和Number对象
2015/01/26 Javascript
详解JavaScript对W3C DOM模版的支持情况
2015/06/16 Javascript
Javascript技术难点之apply,call与this之间的衔接
2015/12/04 Javascript
jQuery基本筛选选择器实例代码
2017/02/06 Javascript
微信小程序 开发之顶部导航栏实例代码
2017/02/23 Javascript
js实现上下左右弹框划出效果
2017/03/08 Javascript
VUE实现表单元素双向绑定(总结)
2017/08/08 Javascript
浅谈Node.js爬虫之网页请求模块
2018/01/11 Javascript
基于Vue渲染与插件的加载顺序的问题详解
2018/03/05 Javascript
浅谈React高阶组件
2018/03/28 Javascript
vue2中,根据list的id进入对应的详情页并修改title方法
2018/08/24 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
p5.js绘制旋转的正方形
2019/10/23 Javascript
Jquery+javascript实现支付网页数字键盘
2020/12/21 jQuery
Python标准库之循环器(itertools)介绍
2014/11/25 Python
关于Python正则表达式 findall函数问题详解
2018/03/22 Python
Python简单实现的代理服务器端口映射功能示例
2018/04/08 Python
python for循环输入一个矩阵的实例
2018/11/14 Python
朴素贝叶斯Python实例及解析
2018/11/19 Python
Python人工智能之路 jieba gensim 最好别分家之最简单的相似度实现
2019/08/13 Python
python实现sm2和sm4国密(国家商用密码)算法的示例
2020/09/26 Python
python 从list中随机取值的方法
2020/11/16 Python
html5中的input新属性range使用记录
2014/09/05 HTML / CSS
正宗的澳大利亚Ugg靴子零售商:UGG Express
2020/04/19 全球购物
分公司经理岗位职责
2013/11/11 职场文书
电子邮箱格式怎么写
2014/01/12 职场文书
理工学院学生自我鉴定
2014/02/23 职场文书
以幸福为主题的活动方案
2014/08/22 职场文书