在 Python 中实现观察者模式的具体步骤是什么?

在 Python 中实现观察者模式可以遵循以下具体步骤,这些步骤清晰地划分了角色和交互流程:

步骤 1:定义主题(Subject)基类

主题是被观察的对象,负责管理观察者和发送通知。需实现以下核心方法:

  • 存储观察者的容器(如列表)
  • 添加观察者的方法(attach
  • 移除观察者的方法(detach
  • 通知所有观察者的方法(notify
python 复制代码
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, *args, **kwargs):
        """通知所有观察者状态变化"""
        for observer in self._observers:
            observer.update(*args, **kwargs)  # 调用观察者的更新方法

步骤 2:实现具体主题(ConcreteSubject)

具体主题是实际业务对象,维护自身状态,当状态变化时触发通知。

python 复制代码
class WeatherStation(Subject):  # 继承主题基类
    def __init__(self):
        super().__init__()
        self._temperature = None  # 示例:温度状态

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

    @temperature.setter
    def temperature(self, new_temp):
        self._temperature = new_temp  # 更新状态
        self.notify(new_temp)  # 状态变化时通知观察者

步骤 3:定义观察者(Observer)基类/接口

观察者是接收通知的对象,需定义一个更新方法(update),供主题调用。

python 复制代码
class Observer:
    def update(self, *args, **kwargs):
        """接收主题通知的方法,子类必须实现"""
        raise NotImplementedError("子类必须重写 update 方法")

步骤 4:实现具体观察者(ConcreteObserver)

具体观察者根据自身需求实现update方法,处理主题发送的通知。

python 复制代码
class PhoneDisplay(Observer):  # 手机显示屏观察者
    def update(self, temp):
        print(f"手机显示:当前温度 {temp}°C")

class WindowDisplay(Observer):  # 窗口显示屏观察者
    def update(self, temp):
        print(f"窗口显示:温度更新为 {temp}°C")

步骤 5:使用观察者模式

创建主题和观察者实例,关联它们,并触发状态变化验证效果。

python 复制代码
# 1. 创建主题(被观察者)
weather_station = WeatherStation()

# 2. 创建观察者
phone_display = PhoneDisplay()
window_display = WindowDisplay()

# 3. 注册观察者到主题
weather_station.attach(phone_display)
weather_station.attach(window_display)

# 4. 改变主题状态(自动通知观察者)
print("--- 温度变为 25°C ---")
weather_station.temperature = 25

print("\n--- 温度变为 30°C ---")
weather_station.temperature = 30

# 5. 移除一个观察者
weather_station.detach(phone_display)
print("\n--- 移除手机显示后,温度变为 28°C ---")
weather_station.temperature = 28

执行结果

复制代码
--- 温度变为 25°C ---
手机显示:当前温度 25°C
窗口显示:温度更新为 25°C

--- 温度变为 30°C ---
手机显示:当前温度 30°C
窗口显示:温度更新为 30°C

--- 移除手机显示后,温度变为 28°C ---
窗口显示:温度更新为 28°C

核心逻辑总结

  1. 主题与观察者解耦 :主题只需知道观察者有update方法,无需了解其具体实现;观察者也无需知道主题的内部逻辑。
  2. 动态关联 :通过attachdetach可以随时添加/移除观察者,灵活性高。
  3. 自动通知 :主题状态变化时,主动调用所有注册观察者的update方法,实现"一处变化,多处响应"。

这种模式适用于事件监听、状态同步、发布-订阅系统等场景,例如 GUI 中的按钮点击事件、数据更新通知等。

相关推荐
m0_626535203 小时前
力扣题目练习 换水问题
python·算法·leetcode
一匹电信狗3 小时前
【LeetCode_160】相交链表
c语言·开发语言·数据结构·c++·算法·leetcode·stl
软件技术NINI3 小时前
MATLAB疑难诊疗:从调试到优化的全攻略
javascript·css·python·html
曦樂~3 小时前
【Qt】信号与槽(Signal and Slot)- 简易计算器
开发语言·数据库·qt
歪歪1003 小时前
React Native开发Android&IOS流程完整指南
android·开发语言·前端·react native·ios·前端框架
yaoxin5211233 小时前
212. Java 函数式编程风格 - Java 编程风格转换:命令式 vs 函数式(以循环为例)
java·开发语言
Q_Q19632884753 小时前
python+uniapp基于微信小程序的助眠小程序
spring boot·python·小程序·django·flask·uni-app·node.js
ZYMFZ3 小时前
python面向对象
前端·数据库·python
wangqiaowq3 小时前
ImmutableList.of() 是 Google Guava 库 提供的一个静态工厂方法,用于创建一个不可变的(immutable)列表。
开发语言·windows·python