设计模式 | 观察者模式

设计模式 | 观察者模式

观察者模式

定义了对象之间一对多依赖,当一个对象发生改变时,他的所有依赖者会接收到通知并更新状态。这种多对象之间的依赖是松耦合的,之间发生交互但不必了解彼此的实现细节。

松耦合设计的重要性

松耦合的设计可以帮助我们设计具有弹性的系统,将对象之间的依赖程度降到最低,方便在开发过程中对系统的迭代及维护。

观察者模式原理

在我们日常使用的软件当中,这种设计模式是十分常见的。

举个栗子:微博

作为社交网络的一个重要支柱,使用微博的人都会在其中关注某些人,朋友、明星、营销号……大 V 能有成万上数十万的粉丝,而你可能只有一两百,一半还是僵尸号……

这里拿局座举例子,当我们关注局座的微博时,观察者模式便已经起作用了,局座是消息中心,而我们是观察者。

关注局座的微博时,我们便 完成了观察者的注册。当消息中心(局座的微博)更新时,我们这些观察者(粉丝)便会接收到通知,然后前来吃瓜围观,参加战忽局的「 会议」。

某一天,某个吃瓜群众不想关注这些了,便取消了对局座(消息中心)的关注(观察者完成取消注册),这时候当消息中心发布消息时,取消注册的观察者也不会收到消息了。

再某天,局座(消息中心)发现自己的粉丝(观察者)中有僵尸粉,便移除了这些账号,这时候 也完成了观察者的注册取消,往后这些被移除的账号也不会收到来自消息中心的消息。

观察者模式类图

在这里插入图片描述
  • 消息中心/主题 (Subject):可识别其观察者,任意观察者皆可订阅一个消息中心,提供一个观察者与其连接和解除连接的接口。
  • 观察者 (Observer):定义一个自我更新的接口,更具消息中心的变化而发生变化。
  • 具体消息中心/主题 (ConcreteSubject):具体的消息中心,存储观察者的具体订阅内容,其发生改变时,向其观察者发送通知。
  • 具体观察者 (ConcreteObserver):维持一个对具体消息中心的引用,存储与消息中心一致的状态,实现观察者的自我更新接口。

观察者模式 Python 简易实现

上面举了局座的例子,这里就实现一个类似的简易功能

class AbstractSubject:
    def __init__(self):
        self.observers = set()

    # 添加观察者
    def attach(self, observer):
        if observer not in self.observers:
            self.observers.add(observer)

    # 移除观察者
    def detach(self, observer):
        if observer in self.observers:
            self.observers.remove(observer)

    # 通知所有已订阅的观察者
    def notify(self):
        for observer in self.observers:
            observer.update(self)


class AbstractObserver:
    def __init__(self, name):
        self.name = name

    # 更新自身状态
    def update(self, subject):
        print("there is {}, {}'s data has changed: {}".format(self.name, subject.name, subject.data))


class Subject(AbstractSubject):
    def __init__(self, name=None):
        super(Subject, self).__init__()
        self.name = name
        self._data = None

    # Python 语法,设置属性,更安全, 设置为@value.setter
    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, val):
        self._data = val
        self.notify()


class Observer(AbstractObserver):
    pass


def main():
    user1 = Observer('user1')
    user2 = Observer('user2')
    user3 = Observer('user3')
    ju_zuo = Subject('局座')
    ju_zuo.attach(user1)
    ju_zuo.attach(user2)
    ju_zuo.data = "hello world"


if __name__ == "__main__":
    main()

输出结果:


在这里插入图片描述

通过结果可以看出只有user1和 user2 接收到了通知,而没有注册的观察者 user3 则没有接收到通知。

关注就是鼓励
公众号: 一起拧螺丝

你可能感兴趣的:(设计模式 | 观察者模式)