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中类的一些方法分析
Sep 25 Python
Flask入门教程实例:搭建一个静态博客
Mar 27 Python
Python实现MySQL操作的方法小结【安装,连接,增删改查等】
Jul 12 Python
python中requests使用代理proxies方法介绍
Oct 25 Python
简单实现python聊天程序
Apr 01 Python
对pandas中Series的map函数详解
Jul 25 Python
Python代码打开本地.mp4格式文件的方法
Jan 03 Python
django框架面向对象ORM模型继承用法实例分析
Jul 29 Python
python实现ip地址查询经纬度定位详解
Aug 30 Python
解决ROC曲线画出来只有一个点的问题
Feb 28 Python
python虚拟环境模块venv使用及示例
Mar 04 Python
基于PyInstaller各参数的含义说明
Mar 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
PHP5在Apache下的两种模式的安装
2006/09/05 PHP
详解PHP中websocket的使用方法
2016/09/15 PHP
php使用 readfile() 函数设置文件大小大小的方法
2017/08/11 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
PHP实现的贪婪算法实例
2017/10/17 PHP
javascript中的循环语句for语句深入理解
2014/04/04 Javascript
jQuery对于显示和隐藏等常用状态的判断方法
2014/12/13 Javascript
JS非Alert实现网页右下角“未读信息”效果弹窗
2015/09/26 Javascript
微信小程序之小豆瓣图书实例
2016/11/30 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
Vue实现动态响应数据变化
2017/04/28 Javascript
vue与TypeScript集成配置最简教程(推荐)
2017/10/17 Javascript
vue中vee validate表单校验的几种基本使用
2018/06/25 Javascript
解决vue.js this.$router.push无效的问题
2018/09/03 Javascript
js数据类型转换与流程控制操作实例分析
2019/12/18 Javascript
小程序中设置缓存过期的实现方法
2020/01/14 Javascript
小程序表单认证布局及验证详解
2020/06/19 Javascript
JavaScript实现页面高亮操作提示和蒙板
2021/01/04 Javascript
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
python二维码操作:对QRCode和MyQR入门详解
2019/06/24 Python
python原类、类的创建过程与方法详解
2019/07/19 Python
python中with语句结合上下文管理器操作详解
2019/12/19 Python
如何通过安装HomeBrew来安装Python3
2020/12/23 Python
CSS3效果:自定义“W”形运行轨迹实例
2017/03/29 HTML / CSS
CSS3制作酷炫的条纹背景
2017/11/09 HTML / CSS
美国最大的旗帜经销商:Carrot-Top
2018/02/26 全球购物
全球最大运动品牌的男装、女装和童装官方库存商:A&A Sports
2021/01/17 全球购物
经典c++面试题四
2015/05/14 面试题
什么是Connection-oriented Protocol/Connectionless Protocol面向连接的协议/无连接协议
2012/09/06 面试题
绩效专员岗位职责
2013/12/02 职场文书
毕业生个人求职信范例分享
2013/12/17 职场文书
探亲假请假条
2014/04/11 职场文书
节约能源标语
2014/06/17 职场文书
古诗之感恩老师
2019/10/24 职场文书
Java实现斗地主之洗牌发牌
2021/06/14 Java/Android
MySQL 1130异常,无法远程登录解决方案详解
2021/08/23 MySQL