zoukankan      html  css  js  c++  java
  • [python实现设计模式]-4.观察者模式-吃食啦!

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

    我们先从一个故事引入。

    工作日的每天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:Python34python.exe "C:Program Files (x86)JetBrainsPyCharm 5.0.1helperspydevpydevd.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:Python34python.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.

  • 相关阅读:
    Java实现自定义排序
    常用加密算法
    隐式传参
    mybatis-plus多租户的使用
    Python3.x基础学习-类--面向对象
    Python3.x基础学习-函数用法(四)
    Python3.x基础学习-函数用法(三)
    Python3.x基础学习-函数用法(二)
    功能测试经验汇总(--持续更新)
    Python3.x基础学习-函数用法(一)
  • 原文地址:https://www.cnblogs.com/kakaliush/p/5290089.html
Copyright © 2011-2022 走看看