博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[python实现设计模式]-4.观察者模式-吃食啦!
阅读量:5132 次
发布时间:2019-06-13

本文共 5695 字,大约阅读时间需要 18 分钟。

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

我们先从一个故事引入。

 

工作日的每天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 = valueif __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)。观察者模式是满足这一要求的各种设 动的协调 计方案中重要的一种。

 

以上,是我抄的。

 

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

 

# 抽象类 抽象通知者 主题 subjectclass 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()# 抽象观察者 observerclass 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.

 

转载于:https://www.cnblogs.com/kakaliush/p/5290089.html

你可能感兴趣的文章
如何去各型MCU的官网上下载正确的数据手册
查看>>
Ulink2 "No Ulink Device found" 解决办法
查看>>
php使用imagick进行图像处理
查看>>
前端面试题(3)
查看>>
Hadoop伪分布式搭建(本人新手,欢迎大家多多指导和关照)
查看>>
客户端储存
查看>>
MeshLab编译理解
查看>>
String
查看>>
网站搭建 (第01天) 模型设计
查看>>
[翻译]用 Puppet 搭建易管理的服务器基础架构(3)
查看>>
心情随笔——2012121
查看>>
CF-1099 D. Sum in the tree
查看>>
2017年BackBox5和Ubuntu16.04.1国内更新源
查看>>
NASA: Seeing Jupiter(注视木星)
查看>>
软件开发基本原则(一)—— 策略和因素 (转)
查看>>
Linux 查看系统所有用户
查看>>
实验三——for 语句及分支结构else-if
查看>>
国家哲学社会科学文献中心
查看>>
把一些表单属性封装一个JSON
查看>>
module
查看>>