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设计模式之桥接模式原理与用法实例分析
Jan 10 Python
Python分支语句与循环语句应用实例分析
May 07 Python
在python中用url_for构造URL的方法
Jul 25 Python
Python numpy.zero() 初始化矩阵实例
Nov 27 Python
python爬虫开发之Beautiful Soup模块从安装到详细使用方法与实例
Mar 09 Python
python安装读取grib库总结(推荐)
Jun 24 Python
python中Django文件上传方法详解
Aug 05 Python
python使用列表的最佳方案
Aug 12 Python
python 带时区的日期格式化操作
Oct 23 Python
PyTorch中clone()、detach()及相关扩展详解
Dec 09 Python
用python读取xlsx文件
Dec 17 Python
Python机器学习之基于Pytorch实现猫狗分类
Jun 08 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 socket方式提交的post详解
2008/07/19 PHP
joomla内置的表单验证功能使用方法
2010/06/11 PHP
Smarty使用自定义资源的方法
2015/08/08 PHP
node.js中的fs.readlinkSync方法使用说明
2014/12/17 Javascript
JavaScript中window.open用法实例详解
2015/04/15 Javascript
js为什么不能正确处理小数运算?
2015/12/29 Javascript
jQuery form插件之formDdata参数校验表单及验证后提交
2016/01/23 Javascript
JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
2016/02/25 Javascript
真正好用的js验证上传文件大小的简单方法
2016/10/27 Javascript
jQuery EasyUI 获取tabs的实例解析
2016/12/06 Javascript
WebPack基础知识详解
2017/01/16 Javascript
原生JS实现移动端web轮播图详解(结合Tween算法造轮子)
2017/09/10 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
vue video和vue-video-player实现视频铺满教程
2020/10/30 Javascript
[01:50]2014DOTA2西雅图邀请赛 专访欢乐周宝龙
2014/07/08 DOTA
初学python数组的处理代码
2011/01/04 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
Python3.5字符串常用操作实例详解
2019/05/01 Python
Python3.8中使用f-strings调试
2019/05/22 Python
python3常用的数据清洗方法(小结)
2019/10/31 Python
Python线程指南分享
2019/11/19 Python
tensorflow 实现打印pb模型的所有节点
2020/01/23 Python
PYcharm 激活方法(推荐)
2020/03/23 Python
基于打开pycharm有带图片md文件卡死问题的解决
2020/04/24 Python
python实现图像高斯金字塔的示例代码
2020/12/11 Python
移动端开发HTML5页面点击按钮后出现闪烁或黑色背景的解决办法
2018/09/19 HTML / CSS
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
Blancsom美国/加拿大:服装和生活用品供应商
2018/07/27 全球购物
2014年上半年工作自我评价
2014/01/18 职场文书
售房协议书
2014/08/19 职场文书
大学生创业事迹材料
2014/12/30 职场文书
治理商业贿赂工作总结
2015/08/10 职场文书
初中班长竞选稿
2015/11/20 职场文书
2019运动会广播加油稿汇总
2019/08/21 职场文书
python for循环赋值问题
2021/06/03 Python
laravel添加角色和模糊搜索功能的实现代码
2021/06/22 PHP