在 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 中的按鈕點擊事件、數據更新通知等。