Python观察者模式详解:从理论到实战

一、模式简介

观察者模式(Observer Pattern)是一种行为设计模式,允许对象(观察者)订阅另一个对象(被观察者)的状态变化,并在状态改变时自动接收通知。这种模式完美解决了"一对多"的对象间通信问题。

核心思想

  • 发布-订阅机制:被观察者维护观察者列表,当状态变化时自动通知所有观察者
  • 松耦合设计:被观察者不需要知道观察者的具体实现,只需通过统一接口通信
  • 动态关系:观察者可以随时订阅或取消订阅

二、模式组成

python 复制代码
# 抽象观察者接口
class Observer:
    def update(self, message):
        """接收通知的接口方法"""
        pass

# 抽象被观察者接口
class Subject:
    def __init__(self):
        self._observers = []  # 观察者列表

    def attach(self, observer):
        """添加观察者"""
        if observer not in self._observers:
            self._observers.append(observer)

    def detach(self, observer):
        """移除观察者"""
        try:
            self._observers.remove(observer)
        except ValueError:
            pass

    def notify(self, message):
        """通知所有观察者"""
        for observer in self._observers:
            observer.update(message)

三、实战案例:天气预报系统

场景描述

  • 天气站(被观察者)实时监测天气数据
  • 手机APP、显示屏(观察者)需要实时接收天气更新

完整实现

python 复制代码
# 具体被观察者:天气站
class WeatherStation(Subject):
    def __init__(self):
        super().__init__()
        self._temperature = 0

    @property
    def temperature(self):
        return self._temperature

    @temperature.setter
    def temperature(self, value):
        self._temperature = value
        self.notify(f"当前温度更新为:{value}℃")  # 触发通知

# 具体观察者:手机APP
class MobileApp(Observer):
    def update(self, message):
        print(f"手机APP收到通知:{message}")

# 具体观察者:电子显示屏
class DisplayBoard(Observer):
    def update(self, message):
        print(f"显示屏更新:{message}")

# 使用示例
if __name__ == "__main__":
    # 创建被观察者
    weather_station = WeatherStation()

    # 创建观察者
    app = MobileApp()
    display = DisplayBoard()

    # 订阅服务
    weather_station.attach(app)
    weather_station.attach(display)

    # 温度更新(自动触发通知)
    weather_station.temperature = 25
    weather_station.temperature = 28

    # 取消订阅
    weather_station.detach(app)
    weather_station.temperature = 30  # 只有显示屏会收到通知

输出结果

复制代码
手机APP收到通知:当前温度更新为:25℃
显示屏更新:当前温度更新为:25℃
手机APP收到通知:当前温度更新为:28℃
显示屏更新:当前温度更新为:28℃
显示屏更新:当前温度更新为:30℃

四、模式优势

  1. 松耦合设计:被观察者无需知道观察者的具体实现
  2. 动态关系:运行时可以自由添加/移除观察者
  3. 开闭原则:新增观察者无需修改被观察者代码
  4. 广播通信:支持一对多的通知机制

五、应用场景

  1. GUI事件处理(如按钮点击通知多个组件)
  2. 消息订阅系统(如新闻推送)
  3. 分布式系统通信(如微服务间的事件通知)
  4. 数据监控场景(如股票价格实时更新)
  5. 游戏开发(如玩家状态变化通知)

六、进阶技巧

1. 使用弱引用避免内存泄漏

python 复制代码
import weakref

class Subject:
    def __init__(self):
        self._observers = weakref.WeakSet()  # 使用弱引用集合

2. 带过滤器的通知

python 复制代码
def notify(self, message, priority="normal"):
    for observer in self._observers:
        if hasattr(observer, 'priority_filter'):
            if observer.priority_filter(priority):
                observer.update(message)
        else:
            observer.update(message)

3. 异步通知(使用线程池)

python 复制代码
from concurrent.futures import ThreadPoolExecutor

class AsyncSubject(Subject):
    def __init__(self):
        super().__init__()
        self._executor = ThreadPoolExecutor(max_workers=5)

    def notify(self, message):
        for observer in self._observers:
            self._executor.submit(observer.update, message)

七、模式对比

特性 观察者模式 发布-订阅模式
耦合度 中等(直接依赖) 松散(通过中间件)
通信方式 直接通知 通过消息通道
适用场景 单一系统内 跨系统/微服务架构
实现复杂度 简单 较高

八、总结

观察者模式通过巧妙的对象关系设计,实现了高效的通知机制。在Python中实现时:

  1. 定义统一的观察者接口
  2. 被观察者维护观察者列表
  3. 通过属性设置器自动触发通知
  4. 注意内存管理和线程安全

实际应用中可根据需求选择同步/异步通知方式,在需要跨系统通信时可以结合消息队列升级为发布-订阅模式。

扩展思考 :尝试用Python的@property装饰器实现更优雅的数据变更监听,或结合asyncio实现协程版本的观察者模式。

相关推荐
学测绘的小杨13 小时前
CompassFusion:一个从 GNSS 到 GNSS/INS 组合导航的独立工程包
python
zzzzzz31019 小时前
当产品经理说这个很简单:我用Python自动化处理奇葩需求的实战指南
python·pycharm·产品经理
雪隐20 小时前
个人电脑玩AI-06让5060 Ti给你打工——不光能画画,Qwen3-TTS还能学人说话,连我老板都信了!
人工智能·后端·python
兵慌码乱1 天前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
hboot1 天前
AI工程师第三课 - 机器学习基础
python·scikit-learn·kaggle
顾林海2 天前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱2 天前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
曲幽2 天前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
荣码2 天前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
兵慌码乱2 天前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理