在 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 中的按钮点击事件、数据更新通知等。

相关推荐
山峰哥1 分钟前
现代 C++ 的炼金术:铸就高性能与高可维护性的工程实践
java·开发语言·前端·数据结构·c++
B站计算机毕业设计之家2 分钟前
大数据:基于python唯品会商品数据可视化分析系统 Flask框架 requests爬虫 Echarts可视化 数据清洗 大数据技术(源码+文档)✅
大数据·爬虫·python·信息可视化·spark·flask·唯品会
27669582923 分钟前
闪购商家端 mtgsig
java·python·c#·node·c·mtgsig·mtgsig1.2
AndrewHZ4 分钟前
【Python与生活】Python文本分析:解码朱自清散文的语言密码
python·beautifulsoup·jieba·语言学·文本分析·文学分析·朱自清
小尧嵌入式6 分钟前
QT软件开发知识流程及秒表计时器开发
开发语言·c++·qt·算法
ULTRA??6 分钟前
强化学习算法分类,工具箱AI总结
开发语言·c++·人工智能
GISer_Jing8 分钟前
Next.js 15 全栈开发实战指南
开发语言·javascript·ecmascript
JIngJaneIL10 分钟前
基于Java在线考试管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot
JIngJaneIL14 分钟前
基于Java音乐管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
繁华似锦respect19 分钟前
C++ 智能指针设计模式详解
服务器·开发语言·c++·设计模式·visual studio