Python设计模式之观察者模式丨【生长吧!Python】

举报
lwq1228 发表于 2021/07/10 14:14:57 2021/07/10
【摘要】 观察者模式,顾名思义就是观察与被观察的关系。观察者模式是对象的行为模式,又叫发布/订阅(Publish/Subscribe)模式、模型/视图(Model/View)模式、源/监听器(Source/Listener)模式或从属者(Dependents)模式。当你看这些模式的时候,不要觉得陌生,它们就是观察者模式。观察者的核心思想就是在被观察者与观察者之间建立一种自动触发的关系。

1、什么是观察者模式

在对象间定义一种一对多的依赖关系,当这个对象状态发生改变时,所有依赖它的对象都会被通知并自动更新。观察者模式是一种一对多的关系,可以有任意个(一个或多个)观察者对象同时监听某一个对象。监听的对象叫观察者,被监听的对象叫被观察者(Observable,也叫主题,即Subject)。被观察者对象在状态或内容(数据)发生变化时,会通知所有观察者对象,使它们能够做出相应的变化(如自动更新自己的信息)。

2、观察者模式设计思想

观察者模式,顾名思义就是观察与被观察的关系。观察者模式是对象的行为模式,又叫发布/订阅(Publish/Subscribe)模式、模型/视图(Model/View)模式、源/监听器(Source/Listener)模式或从属者(Dependents)模式。当你看这些模式的时候,不要觉得陌生,它们就是观察者模式。观察者的核心思想就是在被观察者与观察者之间建立一种自动触发的关系。

3、观察者模式的模型抽象

3.1、代码框架

from abc import ABCMeta, abstractmethod


# 引入ABCMeta 和 abstractmethod来定义抽象类和抽象方法
class Observer(metaclass=ABCMeta):
    """观察者的基类"""

    @abstractmethod
    def update(self, observable, object):
        pass


class Observable:
    """被观察者的基类"""

    def __init__(self):
        self.__observers = []

    def addObserver(self, observer):
        self.__observers.append(observer)

    def removeObserver(self, observer):
        self.__observers.remove(observer)

    def notifyObservers(self, object=0):
        for o in self.__observers:
            o.update(self, object)

3.2、类图

Observable是被观察者的抽象类,Observer是观察者的抽象类。addObserver、removeObserver分别用于添加和删除观察者,notifyObservers 用于内容或状态变化时通知所有的观察者。因为Observable的notifyObservers会调用Observer的update方法,所有观察者不需要关心被观察的对象什么时候会发生变化,只要有变化就会自动调用update,所以只需要关注update实现就可以了。

3.3、模型说明

1、设计要点

1)要明确谁是观察者谁是被观察者。一般观察者与被观察者之间是多对一的关系,一个被观察对象可以有多个观察者。
(2)Observable 在发送广播通知的时候,无须指定具体的 Observer,Observer可以自己决定是否订阅Subject的通知。
(3)被观察者至少需要有三个方法:添加监听者、移除监听者、通知Observer的方法。观察者至少要有一个方法:更新方法,即更新当前的内容,做出相应的处理。
(4)添加观察者和移除观察者在不同的模型称谓中可能会有不同命名,如在观察者模型中一般是addObserver/removeObserver;在源/监听器(Source/Listener)模型中一般是attach/detach,应用在桌面编程的窗口中还可能是attachWindow/detachWindow或Register/UnRegister。不要被名称弄迷糊了,不管它们是什么名称,其实功能都是一样的,就是添加或删除观察者。

2、推模型和拉模型

监听模式根据其侧重的功能还可以分为推模型和拉模型。

推模型:

被观察者对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。一般在这种模型的实现中,会把被观察者对象中的全部或部分信息通过update参数传递给观察者(update(Object obj),通过obj参数传递)。

拉模型:

被观察者在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到被观察者对象中获取,相当于观察者从被观察者对象中拉数据。一般在这种模型的实现中,会把被观察者对象自身通过 update 方法传递给观察者(update(Observable observable),通过observable 参数传递),这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。

3、总结说明

推模型和拉模型其实更多的是语义和逻辑上的区别。我们前面的代码框架,从接口[update(self,observer,object)]上你应该可以知道是同时支持推模型和拉模型的。作为推模型时,observer可以传空,推送的信息全部通过object传递;作为拉模型时,observer和object都传递数据,或只传递observer,需要更具体的信息时通过observer引用去取数据。

4、应用场景

1)对一个对象状态或数据的更新需要其他对象同步更新,或者一个对象的更新需要依赖另一个对象的更新。
(2)对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节,如消息推送。

【生长吧!Python】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/278897

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。