2024-简单点-观察者模式

先看代码:

python 复制代码
# 导入未来模块以支持类型注解
from __future__ import annotations

# 导入抽象基类模块和随机数生成器
from abc import ABC, abstractmethod
from random import randrange

# 导入列表类型注解
from typing import List


# 定义观察者模式中的主体接口(Subject)
class Subject(ABC):

    """
    主体接口声明一组用于管理订阅者的方法。
    """

    @abstractmethod
    def attach(self, observer: Observer) -> None:
        """
        将观察者附加到主体。
        """
        pass

    @abstractmethod
    def detach(self, observer: Observer) -> None:
        """
        从主体中移除观察者。
        """
        pass

    @abstractmethod
    def notify(self) -> None:
        """
        通知所有观察者有关事件的信息。
        """
        pass


# 定义具体主体类(ConcreteSubject)
class ConcreteSubject(Subject):

    """
    具体主体拥有对所有订阅者至关重要的状态,并在状态变化时通知观察者。
    """

    _state: int = None

    """
    为了简化起见,主体的状态(对所有订阅者至关重要)存储在此变量中。
    """

    _observers: List[Observer] = []

    """
    订阅者列表。在实际应用中,订阅者列表可以更全面地存储(按事件类型分类等)。
    """

    def attach(self, observer: Observer) -> None:
        print("主体:已附加一个观察者。")
        self._observers.append(observer)

    def detach(self, observer: Observer) -> None:
        self._observers.remove(observer)

    """
    订阅管理方法。
    """

    def notify(self) -> None:
        """
        触发每个订阅者的更新。
        """
        print("主体:正在通知观察者...")
        for observer in self._observers:
            observer.update(self)

    def some_business_logic(self) -> None:
        """
        通常,订阅逻辑只是主体所能做的工作的一部分。主体通常包含一些重要的业务逻辑,
        当即将发生(或已经发生)重要事情时触发通知方法。
        """
        print("\n主体:我正在做一些重要的事情。")
        self._state = randrange(0, 10)
        print(f"主体:我的状态刚刚变更为:{self._state}")
        self.notify()


# 定义观察者接口(Observer)
class Observer(ABC):

    """
    观察者接口声明由主体使用的update方法。
    """

    @abstractmethod
    def update(self, subject: Subject) -> None:
        """
        接收主体的更新。
        """
        pass


# 定义具体观察者类(ConcreteObserverA 和 ConcreteObserverB)
"""
具体观察者对它们所附属的主体发出的更新做出反应。
"""

class ConcreteObserverA(Observer):
    def update(self, subject: Subject) -> None:
        if subject._state < 3:
            print("具体观察者A:对事件作出反应")

class ConcreteObserverB(Observer):
    def update(self, subject: Subject) -> None:
        if subject._state == 0 or subject._state >= 2:
            print("具体观察者B:对事件作出反应")


# 客户端代码
if __name__ == "__main__":
    subject = ConcreteSubject()

    observer_a = ConcreteObserverA()
    subject.attach(observer_a)

    observer_b = ConcreteObserverB()
    subject.attach(observer_b)

    subject.some_business_logic()
    subject.some_business_logic()

    subject.detach(observer_a)

    subject.some_business_logic()

输出

python 复制代码
Subject: Attached an observer.
Subject: Attached an observer.

Subject: I'm doing something important.
Subject: My state has just changed to: 0
Subject: Notifying observers...
ConcreteObserverA: Reacted to the event
ConcreteObserverB: Reacted to the event

Subject: I'm doing something important.
Subject: My state has just changed to: 5
Subject: Notifying observers...
ConcreteObserverB: Reacted to the event

Subject: I'm doing something important.
Subject: My state has just changed to: 0
Subject: Notifying observers...
ConcreteObserverB: Reacted to the event

参考:
参考

相关推荐
浪客川1 分钟前
【百例RUST - 015】闭包
开发语言·后端·rust
HHHHH1010HHHHH2 分钟前
Golang怎么用Go实现待办事项API_Golang如何用RESTful风格实现Todo应用后端接口【教程】
jvm·数据库·python
Acnidouwo3 分钟前
QT程序的dpi导致显示异常处理方法
开发语言·qt
weixin_381288184 分钟前
CSS代码如何快速重构_使用Sass的@import逻辑重组结构
jvm·数据库·python
m0_716430075 分钟前
Go语言怎么做自动补全_Go语言CLI自动补全教程【经典】
jvm·数据库·python
金融大 k5 分钟前
Python + Redis 实时行情共享:WebSocket 数据流的订阅管理与断线恢复实践
redis·python·websocket
初心未改HD5 分钟前
Python零基础到精通教程,数据分析(数据处理,挖掘价值)
开发语言·python
m0_674294648 分钟前
MongoDB评论回复系统怎么建表_多级嵌套与展平设计思路
jvm·数据库·python
源码之家8 分钟前
计算机毕业设计:Python农业数据分析与粮食产量预测系统 Django框架 数据分析 可视化 机器学习 深度学习 大数据 大模型(建议收藏)✅
python·机器学习·信息可视化·数据分析·django·flask·课程设计
m0_493934538 分钟前
React 中父组件向子组件传递函数的正确方式
jvm·数据库·python