在 Python 中实现观察者模式可以遵循以下具体步骤,这些步骤清晰地划分了角色和交互流程:
步骤 1:定义主题(Subject)基类
主题是被观察的对象,负责管理观察者和发送通知。需实现以下核心方法:
- 存储观察者的容器(如列表)
- 添加观察者的方法(
attach
) - 移除观察者的方法(
detach
) - 通知所有观察者的方法(
notify
)
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)
具体主题是实际业务对象,维护自身状态,当状态变化时触发通知。
class WeatherStation(Subject): # 继承主题基类def __init__(self):super().__init__()self._temperature = None # 示例:温度状态@propertydef temperature(self):return self._temperature@temperature.setterdef temperature(self, new_temp):self._temperature = new_temp # 更新状态self.notify(new_temp) # 状态变化时通知观察者
步骤 3:定义观察者(Observer)基类/接口
观察者是接收通知的对象,需定义一个更新方法(update
),供主题调用。
class Observer:def update(self, *args, **kwargs):"""接收主题通知的方法,子类必须实现"""raise NotImplementedError("子类必须重写 update 方法")
步骤 4:实现具体观察者(ConcreteObserver)
具体观察者根据自身需求实现update
方法,处理主题发送的通知。
class PhoneDisplay(Observer): # 手机显示屏观察者def update(self, temp):print(f"手机显示:当前温度 {temp}°C")class WindowDisplay(Observer): # 窗口显示屏观察者def update(self, temp):print(f"窗口显示:温度更新为 {temp}°C")
步骤 5:使用观察者模式
创建主题和观察者实例,关联它们,并触发状态变化验证效果。
# 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 = 25print("\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
核心逻辑总结
- 主题与观察者解耦:主题只需知道观察者有
update
方法,无需了解其具体实现;观察者也无需知道主题的内部逻辑。 - 动态关联:通过
attach
和detach
可以随时添加/移除观察者,灵活性高。 - 自动通知:主题状态变化时,主动调用所有注册观察者的
update
方法,实现"一处变化,多处响应"。
这种模式适用于事件监听、状态同步、发布-订阅系统等场景,例如 GUI 中的按钮点击事件、数据更新通知等。