观察者模式是一个非常重要的设计模式.

我们先从一个故事引入。

工作日的每天5点左右,大燕同学都会给大家订饭。

然后7点左右,饭来了。

于是燕哥大吼一声,“饭来啦!”,5点钟定过饭的同学就会纷纷涌入餐厅吃饭。

这就是一个典型的观察者模式的场景。

所有订饭的同学都是观察者。一旦观察到大燕吼了一声“feeding time!”, 大家就知道该吃食了。

喜欢吃辣的就去吃辣,喜欢吃臭的就去吃臭....

那么,用python 实现一版。

class: 点饭小秘大燕, attach方法,把点饭人加入到点饭大军列表, detach 把点饭人踢掉,不让他吃饭。

class:点饭人菜菜

class:点饭人高明

# 点饭小秘书大燕
class Secretary: def __init__(self):
self.__name = "daisy"
self.__status = "打瞌睡中" # 观察者们
observers = [] @property
def status(self):
return self.__status @status.setter
def status(self, value):
print('我擦 ' + value)
self.__status = value def attach(self, observer):
print('%s, 我要订饭....' % observer.name)
Secretary.observers.append(observer) def detach(self, observer):
print('%s, 得罪了我,定了也白订....' % observer.name)
Secretary.observers.remove(observer)
pass def notify(self):
for observer in Secretary.observers:
observer.update() # 观察者菜菜
class ObserverYicai: secretary = None def __init__(self, secretary):
self.__name = "yi.cai"
ObserverYicai.secretary = secretary def update(self):
if ObserverYicai.secretary.status == "饭来了":
print('i am %s,%s' % (self.__name, '我不吃辣,我喝汤')) @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value # 观察者高明
class ObserverGaoming: secretary = None def __init__(self, secretary):
self.__name = "gaoming"
ObserverYicai.secretary = secretary def update(self):
if ObserverYicai.secretary.status == "饭来了":
print('i am %s,%s' % (self.__name, '臭的也挺好吃...')) @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value if __name__ == "__main__":
daisy = Secretary() yicai = ObserverYicai(daisy)
gaoming = ObserverGaoming(daisy) daisy.attach(yicai)
daisy.attach(gaoming) daisy.status = "饭来了" daisy.notify()

运行结果:

C:\Python34\python.exe "C:\Program Files (x86)\JetBrains\PyCharm 5.0.1\helpers\pydev\pydevd.py" --multiproc --qt-support --client 127.0.0.1 --port 64162 --file C:/Users/trump/PycharmProjects/untitled/Observer/Observer.py
pydev debugger: process 184 is connecting

Connected to pydev debugger (build 143.595)
yi.cai, 我要订饭....
gaoming, 我要订饭....
我擦 饭来了
i am yi.cai,我不吃辣,我喝汤
i am gaoming,臭的也挺好吃...

Process finished with exit code 0

猛一看,嗯。这段代码写得不错....(自我陶醉3秒钟...)

仔细一看,其实是很想比了狗的。

为什么捏?

点饭小蜜耦合了观察者,观察者耦合了点饭小蜜.....

强耦合.....这跟我们高内聚低耦合的设计模式理念完全不符哇!!

两个观察者的代码一模一样啊,有代码强迫症的我完全受不鸟啊!!

于是,几个聪明的脑瓜GOF,俗称四人帮,想了一个模式。这个模式就叫观察者模式。

闪亮登场!

观察者(Observer)模式
观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、 源 听器(Source/Listener)模式或从属者(Dependents)模式。 -监
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主
题对象在 所有观察者对象,使它们能够自动更新自己。 状态上发生变化时,会通知
一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其它的对象做出相应的改变。
做 方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。 到这一点的设计
减 系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维 少对象之间的耦合有利于
持行 一致,保证高度的协作(Collaboration)。观察者模式是满足这一要求的各种设 动的协调 计方案中重要的一种。

以上,是我抄的。

根据观察者模式,我们来重写我们的代码。

# 抽象类 抽象通知者 主题 subject
class Subject:
# 定义为抽象类
__metaclass__ = ABCMeta def __init__(self):
self.__status = ''
pass @abstractmethod
def attach(self, observer):
pass @abstractmethod
def detach(self, observer):
pass @abstractmethod
def notify(self):
pass @property
def status(self):
return self.__status @status.setter
def status(self, value):
print('我擦 ' + value)
self.__status = value # 通知者 点餐小蜜大燕
class Secretary(Subject): observers = [] def attach(self, observer):
print('%s, 我要订饭....' % observer.name)
Secretary.observers.append(observer) def detach(self, observer):
print('%s, 得罪了我,定了也白订....' % observer.name)
Secretary.observers.remove(observer)
pass def notify(self):
for observer in Secretary.observers:
observer.update() # 抽象观察者 observer
class Observer:
# 定义为抽象类
__metaclass__ = ABCMeta # 约束子类必须实现update方法
@abstractmethod
def update(self):
pass # 观察者菜菜
class ObserverYicai(Observer):
subject = None def __init__(self, subject):
ObserverYicai.subject = subject
self.__name = 'yi.cai' def update(self):
if ObserverYicai.subject.status == "饭来了":
print('i am %s,%s' % (self.__name, '我不吃辣,我喝汤')) @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value # 观察者高明
class ObserverGaoming(Observer):
subject = None def __init__(self, subject):
ObserverYicai.subject = subject
self.__name = 'gaoming' def update(self):
if ObserverYicai.subject.status == "饭来了":
print('i am %s,%s' % (self.__name, '臭的也挺好吃...')) @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value
if __name__ == "__main__":
daisy = Secretary() yicai = ObserverYicai(daisy)
gaoming = ObserverGaoming(daisy) daisy.attach(yicai)
daisy.attach(gaoming) daisy.status = "饭来了" daisy.notify() print('第二天,高明得罪了大燕') daisy.detach(gaoming) daisy.notify()

运行:

C:\Python34\python.exe C:/Users/trump/PycharmProjects/untitled/Observer/Observer.py
yi.cai, 我要订饭....
gaoming, 我要订饭....
我擦 饭来了
i am yi.cai,我不吃辣,我喝汤
i am gaoming,臭的也挺好吃...
第二天,高明得罪了大燕
gaoming, 得罪了我,定了也白订....
i am yi.cai,我不吃辣,我喝汤

谔谔谔谔谔谔谔谔谔谔.....

呃呃呃呃呃呃呃...

为什么感觉和第一版没什么区别呢...

主要原因是因为python 是弱类型语言.....于是感觉不出传接口和传实际的类有何不同...

我得再好好思考下.....

在.net 中, 微软非常优雅的使用委托和事件实现了观察者模式.

通过一个object 的sender 实现事件发送方

所有订阅过事件的对象将会通过委托收到事件发生的细节.

事件的所有细节包括在EventArgs中.

以上,观察者模式...

to be continued.

[python实现设计模式]-4.观察者模式-吃食啦!的更多相关文章

  1. [转]Python与设计模式

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

  2. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  3. 设计模式之观察者模式(Observable与Observer)

    设计模式之观察者模式(Observable与Observer) 好久没有写博客啦,之前看完了<设计模式之禅>也没有总结一下,现在回忆一下设计模式之观察者模式. 1.什么是观察者模式 简单情 ...

  4. 8.5 GOF设计模式四: 观察者模式Observer

    GOF设计模式四: 观察者模式Observer  现实中遇到的问题  当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式  观察者模式 ...

  5. Python与设计模式之创建型模式及实战

    用Python学习一下设计模式,如果很枯燥的话,就强行能使用的就用一下.设计模式参考Python与设计模式-途索 1. 单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点. import ...

  6. php 设计模式之观察者模式(订阅者模式)

    php 设计模式之观察者模式 实例 没用设计模式的代码,这样的代码要是把最上面那部分也要符合要求加进来,就要修改代码,不符合宁增不改的原则 介绍 观察者模式定义对象的一对多依赖,这样一来,当一个对象改 ...

  7. [JS设计模式]:观察者模式(即发布-订阅者模式)(4)

    简介 观察者模式又叫发布---订阅模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 举一个现实生活中的例子,例如小 ...

  8. Python使用设计模式中的责任链模式与迭代器模式的示例

    Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...

  9. 实践GoF的23种设计模式:观察者模式

    摘要:当你需要监听某个状态的变更,且在状态变更时通知到监听者,用观察者模式吧. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:观察者模式>,作者: 元闰子 . 简介 现在有 ...

随机推荐

  1. win10下 homestead 安装

    1.安装VirtualBox 和 Vagrant 2.git或者composer安装 homestead git clone https://github.com/laravel/homestead. ...

  2. Android深度探索HAL和驱动开发(卷1) 第一章 Android系统移植和驱动开发

    由于Android是基于Linux内核的,因此,Android和其他Linux系统的核心部分差异非常小.然而不同版本的Android使用的Linux内核的版本有细微的差异,所以不同Android驱动可 ...

  3. FZU-2075 Substring(后缀数组)

    Description Given a string, find a substring of it which the original string contains exactly n such ...

  4. css3新增的属性选择器

    使用css选择器,可以实现一个样式对应多个html文档的元素,在{}前面的部分就是"选择器",指明了样式的作用对象. 在CSS中追加了三个属性选择器:[att*=val].[att ...

  5. REGEX.C GNU 提取过滤数据

    今天被@SVCHAO  勾起兴趣来了.. 有把正则表达式兴趣捡起来了,试了下notepad++基本上语法倒是没有忘记,不过如果是用在嵌入式的方案的话,似乎还是有点费劲的. 先mark一个基础语法. 单 ...

  6. Android 从图库到选择图片onActivityResult接收注意的问题

    从图库选择图片然后返回数据接收处理的时候,这个时候我们可能会遇到一个问题.就是明明我走了返回的代码.但是为什么我的图片路径没有拿到?这个时候可能是Android的api不同导致,因为Android4. ...

  7. Win10下SQLServer2000的安装

    Win10的技术预览版已经发布近两个星期了,我也迫不及待地装上尝鲜,发现SQLServer2000在Win10上无法安装,在翻遍网上资料和经过无数次尝试后得到了一种安装方法,希望能够帮助遇到类似问题的 ...

  8. Python爬虫库Scrapy入门1--爬取当当网商品数据

    1.关于scrapy库的介绍,可以查看其官方文档:http://scrapy-chs.readthedocs.io/zh_CN/latest/ 2.安装:pip install scrapy  注意这 ...

  9. Orchard学习笔记

    1.下载Orchard sourcrs资源文件,同时也可以去百度下载中文包 资源地址(https://github.com/OrchardCMS/Orchard/releases/download/1 ...

  10. MSSQL-实用小工具

    1.创建查询辅助表 create table nums (n int not null) alter table nums add constraint PK_NUMS primary key clu ...