【Python笔记-设计模式】观察者模式

一、说明

观察者模式是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知"监控"该对象的其他对象。

(一) 解决问题

主要解决一个对象的状态变化时,需要通知其他对象,并且这些被通知的对象可能是多个且不确定的。

(二) 使用场景

  • 应用中的一些对象必须观察其他对象状态并进行操作时,如消息订阅、动态推送
  • 当一个对象状态的改变需要改变其他对象,或实际对象是事先未知的或动态变化的时

二、结构

  1. **发布者(Publisher)**会向其他对象发送值得关注的事件。事件会在发布者自身状态改变或执行特定行为后发生。发布者中包含一个允许新订阅者加入和当前订阅者离开列表的订阅构架。
  2. 当新事件发生时,发送者会遍历订阅列表并调用每个订阅者对象的通知方法。该方法是在订阅者接口中声明的。
  3. **订阅者(Subscriber)**接口声明了通知接口。在绝大多数情况下,该接口仅包含一个update更新方法。该方法可以拥有多个参数,使发布者能在更新时传递事件的详细信息。
  4. **具体订阅者(ConcreteSubscribers)**可以执行一些操作来回应发布者的通知。所有具体订阅者类都实现了同样的接口,因此发布者不需要与具体类相耦合。
  5. 订阅者通常需要一些上下文信息来正确地处理更新。因此,发布者通常会将一些上下文数据作为通知方法的参数进行传递。发布者也可将自身作为参数进行传递,使订阅者直接获取所需的数据。
  6. **客户端(Client)**会分别创建发布者和订阅者对象,然后为订阅者注册发布者更新。

三、伪代码

python 复制代码
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
观察者模式

例:股票价格监控,当股票价格变化时,通知所有订阅者
"""

from abc import ABC, abstractmethod
from typing import List


class Subject(ABC):
    """发布者基类"""

    @abstractmethod
    def register_observer(self, observer):
        pass

    @abstractmethod
    def remove_observer(self, observer):
        pass

    @abstractmethod
    def notify_observers(self):
        pass


class Observer(ABC):
    """订阅者基类"""

    @abstractmethod
    def update(self):
        pass


class StockPriceSubject(Subject):
    """具体发布者"""

    def __init__(self):
        self._observers: List[Observer] = []
        self._price = 0.0

    def register_observer(self, observer):
        self._observers.append(observer)

    def remove_observer(self, observer):
        self._observers.remove(observer)

    def notify_observers(self):
        for observer in self._observers:
            observer.update()

    def set_price(self, price):
        self._price = price
        self.notify_observers()

    def get_price(self):
        return self._price


class Investor(Observer):
    """具体订阅者"""

    def __init__(self, name, subject):
        self._name = name
        self._subject = subject

    def update(self):
        price = self._subject.get_price()
        print(f"{self._name} 收到新价格: {price}")


if __name__ == "__main__":
    """
        张三 收到新价格: 100.0
        李四 收到新价格: 100.0
        ------------------------------
        张三 收到新价格: 110.0
    """
    stock_subject = StockPriceSubject()

    investor1 = Investor("张三", stock_subject)
    investor2 = Investor("李四", stock_subject)

    stock_subject.register_observer(investor1)
    stock_subject.register_observer(investor2)
    # 股票变动自动通知订阅者
    stock_subject.set_price(100.0)

    print("-" * 30)

    # 李四取消订阅订阅
    stock_subject.remove_observer(investor2)
    stock_subject.set_price(110.0)

四、优缺点

优点

  • **开闭原则:**可以在不修改主题和观察者类的情况下增加新的观察者
  • **主题和观察者之间是松耦合的:**主题对象不需要知道观察者的具体实现,只需要知道观察者接口即可。这样可以降低对象之间的耦合度,使得系统更加灵活。

缺点

  • 如果观察者很多,通知所有观察者可能会导致性能问题。
  • 如果观察者和主题之间有循环依赖,可能会导致系统复杂性增加。

【Python笔记】设计模式-CSDN博客

相关推荐
神的孩子都在歌唱1 天前
行为设计模式 -观察者模式- JAVA
java·观察者模式·设计模式
It'sMyGo4 天前
js设计模式-工厂模式 单例模式 观察者模式 发布订阅模式 原型模式 代理模式 迭代器模式
观察者模式·单例模式·设计模式
java_heartLake9 天前
设计模式之观察者模式
java·观察者模式·设计模式
林小果19 天前
观察者模式
java·开发语言·观察者模式·设计模式
shanshan20999 天前
观察者模式在C#实际应用中的使用:PLC数据监控
观察者模式
潘多编程9 天前
Spring Boot 实战:使用观察者模式实现实时库存管理
spring boot·后端·观察者模式
学步_技术11 天前
Python编码系列—Python观察者模式:实现事件驱动架构的利器
python·观察者模式·架构
赤橙红的黄11 天前
观察者模式(发布-订阅模式)
java·开发语言·观察者模式
仙魁XAN12 天前
Unity 设计模式 之 行为型模式 -【状态模式】【观察者模式】【备忘录模式】
观察者模式·unity·设计模式·状态模式·备忘录模式
coffee_baby13 天前
观察者模式全攻略:从设计原理到 SpringBoot 实践案例
spring boot·后端·观察者模式