📜  Python设计模式-观察者(1)

📅  最后修改于: 2023-12-03 15:19:36.189000             🧑  作者: Mango

Python设计模式-观察者

简介

观察者模式是一种行为型设计模式,它允许对象之间建立一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。

在软件开发过程中,经常需要实现模块之间的通信和事件响应,观察者模式可以帮助解决此类问题。观察者模式具有松耦合、可拓展和复用性强等优点,广泛应用于桌面应用程序、Web应用程序、企业应用程序等系统中。

实现方式

观察者模式包含以下角色:

  1. 抽象主题(Subject):抽象主题是被观察的对象,它可以被多个观察者观察,提供注册观察者、删除观察者、通知观察者等方法。
  2. 具体主题(ConcreteSubject):具体主题是抽象主题的一种实现,它维护观察者列表,并在状态改变时通知所有观察者。
  3. 抽象观察者(Observer):抽象观察者定义观察者的一些常用方法,例如更新状态等。
  4. 具体观察者(ConcreteObserver):具体观察者是抽象观察者的一种实现,它保存了一个指向具体主题的引用,通过该引用可以获取具体主题的状态,并对其做出响应。

观察者模式的关键是对主题(被观察者)和观察者的定义。主题需要维护观察者列表,观察者需要实现更新状态的方法,从而保持主题和观察者之间的松耦合关系。

下面是一个使用Python实现观察者模式的示例代码:

from abc import ABC, abstractmethod

class Subject(ABC):
    """
    抽象主题类,定义被观察对象的接口
    """
    def __init__(self):
        self._observers = []

    def attach(self, observer):
        """
        注册一个观察者对象
        """
        if observer not in self._observers:
            self._observers.append(observer)

    def detach(self, observer):
        """
        从观察者列表中移除一个观察者对象
        """
        if observer in self._observers:
            self._observers.remove(observer)

    def notify(self, *args, **kwargs):
        """
        通知所有注册的观察者对象
        """
        for observer in self._observers:
            observer.update(self, *args, **kwargs)

class ConcreteSubject(Subject):
    """
    具体主题类,继承抽象主题类
    """
    def __init__(self):
        super().__init__()
        self._state = None

    def get_state(self):
        """
        获取主题对象的状态
        """
        return self._state

    def set_state(self, state):
        """
        设置主题对象的状态,并通知所有观察者对象
        """
        self._state = state
        self.notify()

class Observer(ABC):
    """
    抽象观察者类,定义观察者的接口
    """
    @abstractmethod
    def update(self, subject, *args, **kwargs):
        pass

class ConcreteObserver(Observer):
    """
    具体观察者类,继承抽象观察者类
    """
    def update(self, subject, *args, **kwargs):
        """
        更新状态,从具体主题对象获取最新的状态信息
        """
        print(f"{self.__class__.__name__} received update from {subject.__class__.__name__} with args:{args}, kwargs:{kwargs}")

if __name__ == '__main__':
    subject = ConcreteSubject()
    observer1 = ConcreteObserver()
    observer2 = ConcreteObserver()
    subject.attach(observer1)
    subject.attach(observer2)

    subject.set_state("state1")
    subject.set_state("state2")

    subject.detach(observer1)
    subject.set_state("state3")

在上面的示例代码中,我们定义了一个抽象主题类Subject和一个具体主题类ConcreteSubject,并实现了注册观察者、移除观察者和通知观察者的方法。

在抽象观察者类Observer中,我们定义了观察者的更新接口update,在具体观察者类ConcreteObserver中,我们实现了该方法,从而对主题对象状态的改变做出响应。

main函数中,我们创建了一个具体主题对象subject,并注册了两个观察者对象observer1observer2,随后改变主题对象的状态,并通知观察者更新。通过调用detach方法,我们移除了一个观察者,再次改变主题对象状态并通知观察者,发现只有一个观察者收到了通知。

总结

观察者模式是一种行为型设计模式,它允许对象之间建立一对多的依赖关系。观察者模式是松耦合、可拓展和复用性强的特点,广泛应用于桌面应用程序、Web应用程序、企业应用程序等系统中。在Python中实现观察者模式非常方便,只需要定义抽象主题、具体主题、抽象观察者和具体观察者四个角色,并实现对应的方法即可。