观察者模式
外观
观察者模式[编辑 | 编辑源代码]
观察者模式(Observer Pattern)是一种行为设计模式,用于定义对象之间的一对多依赖关系,使得当一个对象(Subject,主题)的状态发生改变时,所有依赖它的对象(Observer,观察者)都会自动收到通知并更新。该模式广泛应用于事件驱动系统、GUI 框架和发布-订阅模型中。
核心概念[编辑 | 编辑源代码]
观察者模式包含以下主要角色:
- Subject(主题):维护一个观察者列表,提供注册(attach)和注销(detach)观察者的方法,并在状态变化时通知观察者。
- Observer(观察者):定义一个更新接口,供主题在状态变化时调用。
- ConcreteSubject(具体主题):实现主题的具体逻辑,存储状态并在状态变化时通知观察者。
- ConcreteObserver(具体观察者):实现观察者的更新逻辑,以响应主题的状态变化。
结构图[编辑 | 编辑源代码]
以下为观察者模式的 UML 类图:
代码示例[编辑 | 编辑源代码]
以下是一个简单的 Python 实现示例,展示观察者模式的基本结构:
from abc import ABC, abstractmethod
# 观察者接口
class Observer(ABC):
@abstractmethod
def update(self, subject):
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):
self._observers.remove(observer)
def notify(self):
for observer in self._observers:
observer.update(self)
# 具体主题:温度传感器
class TemperatureSensor(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() # 温度变化时通知观察者
# 具体观察者:显示屏
class Display(Observer):
def update(self, subject):
print(f"温度更新:{subject.temperature}°C")
# 使用示例
sensor = TemperatureSensor()
display = Display()
sensor.attach(display)
sensor.temperature = 25 # 输出:温度更新:25°C
sensor.temperature = 30 # 输出:温度更新:30°C
输出:
温度更新:25°C 温度更新:30°C
实际应用场景[编辑 | 编辑源代码]
观察者模式在以下场景中非常有用:
- GUI 事件处理:如按钮点击事件通知多个监听器。
- 发布-订阅系统:如消息队列、新闻推送。
- 数据监控:如传感器数据变化时更新多个显示组件。
- MVC 架构:模型(Model)变化时自动更新视图(View)。
案例:股票价格通知[编辑 | 编辑源代码]
假设有一个股票交易系统,当某只股票价格变化时,所有订阅该股票的投资者都会收到通知。
class Stock(Subject):
def __init__(self, symbol, price):
super().__init__()
self.symbol = symbol
self._price = price
@property
def price(self):
return self._price
@price.setter
def price(self, value):
self._price = value
self.notify()
class Investor(Observer):
def __init__(self, name):
self.name = name
def update(self, subject):
print(f"{self.name} 收到通知:{subject.symbol} 最新价格 {subject.price}")
# 使用示例
apple = Stock("AAPL", 150)
investor1 = Investor("张三")
investor2 = Investor("李四")
apple.attach(investor1)
apple.attach(investor2)
apple.price = 155 # 价格变化,通知所有投资者
输出:
张三 收到通知:AAPL 最新价格 155 李四 收到通知:AAPL 最新价格 155
优缺点[编辑 | 编辑源代码]
优点:
- 松耦合:主题和观察者之间依赖最小化。
- 动态订阅:观察者可随时注册或注销。
- 广播通信:主题可一次性通知多个观察者。
缺点:
- 通知顺序不确定:观察者更新顺序可能影响系统行为。
- 性能问题:大量观察者可能导致通知延迟。
数学表示[编辑 | 编辑源代码]
观察者模式可以形式化表示为: 其中:
- 是观察者集合,
- 是主题状态。
总结[编辑 | 编辑源代码]
观察者模式是一种强大的设计模式,适用于需要解耦事件源和事件处理逻辑的场景。通过合理使用该模式,可以构建灵活、可扩展的事件驱动系统。