观察者模式(Observer Pattern)是一种行为型设计模式,主要用于创建一种对象之间的一对多的依赖关系,使得当一个对象状态发生变化时,所有依赖于它的对象都能得到通知并自动更新。这个模式通常用于实现事件处理系统、发布订阅机制等场景。
观察者模式的基本组成
- 主题(Subject):被观察的对象。当它的状态发生变化时,会通知所有的观察者。
 - 观察者(Observer):依赖于主题对象的对象。当主题的状态发生变化时,它会得到通知并更新。
 - 具体主题(Concrete Subject):实现了主题接口的具体类,它会在状态改变时通知所有观察者。
 - 具体观察者(Concrete Observer):实现了观察者接口的具体类,它会在接到通知时做出相应的处理。
 
观察者模式的类图
 +------------------+       +------------------+
 |   Subject        |<>---->|   Observer       |
 |------------------|       |------------------|
 | +attach()        |       | +update()        |
 | +detach()        |       +------------------+
 | +notify()        |
 +------------------+
         ^
         |
         |  
 +--------------------+  +---------------------+
 | ConcreteSubject    |  | ConcreteObserver    |
 +--------------------+  +---------------------+
观察者模式的流程:
- 主题(
Subject)有一个状态,当它的状态发生变化时,需要通知所有的观察者。 - 观察者(
Observer)在注册时会把自己添加到主题的观察者列表中。 - 一旦主题的状态发生变化,它会遍历所有已注册的观察者,并调用它们的更新方法。
 - 观察者在更新时通常会去查询主题的最新状态,并执行相关的操作。
 
代码示例
下面是一个 Python 中观察者模式的简单实现:
# 观察者模式的实现
from abc import ABC, abstractmethod
# 主题类(Subject)
class Subject(ABC):
    def __init__(self):
        self._observers = []  # 观察者列表
    
    def attach(self, observer):
        """添加观察者"""
        self._observers.append(observer)
    
    def detach(self, observer):
        """移除观察者"""
        self._observers.remove(observer)
    
    def notify(self):
        """通知所有观察者"""
        for observer in self._observers:
            observer.update(self)
# 观察者类(Observer)
class Observer(ABC):
    @abstractmethod
    def update(self, subject):
        """接收通知并更新"""
        pass
# 具体主题类(ConcreteSubject)
class ConcreteSubject(Subject):
    def __init__(self):
        super().__init__()
        self._state = None
    
    @property
    def state(self):
        return self._state
    
    @state.setter
    def state(self, value):
        self._state = value
        self.notify()  # 状态变化时通知观察者
# 具体观察者类(ConcreteObserver)
class ConcreteObserver(Observer):
    def __init__(self, name):
        self._name = name
        self._state = None
    
    def update(self, subject):
        """更新状态"""
        self._state = subject.state
        print(f"Observer {self._name} updated with new state: {self._state}")
# 客户端代码
if __name__ == "__main__":
    # 创建具体主题
    subject = ConcreteSubject()
    
    # 创建观察者
    observer1 = ConcreteObserver("Observer 1")
    observer2 = ConcreteObserver("Observer 2")
    
    # 注册观察者
    subject.attach(observer1)
    subject.attach(observer2)
    
    # 改变主题状态,通知所有观察者
    print("Changing state to 10...")
    subject.state = 10
    
    print("\nChanging state to 20...")
    subject.state = 20
    
    # 移除观察者1
    subject.detach(observer1)
    
    print("\nChanging state to 30...")
    subject.state = 30
运行结果:
Changing state to 10...
Observer Observer 1 updated with new state: 10
Observer Observer 2 updated with new state: 10
Changing state to 20...
Observer Observer 1 updated with new state: 20
Observer Observer 2 updated with new state: 20
Changing state to 30...
Observer Observer 2 updated with new state: 30
解释:
ConcreteSubject是具体的主题类,它有一个状态state,当这个状态发生变化时,它会调用notify()方法通知所有观察者。ConcreteObserver是具体的观察者,它会实现update()方法来接收并处理主题的状态变化。- 通过 
attach()方法将观察者添加到主题的观察者列表中,并且通过detach()方法可以将观察者移除。 
观察者模式的优缺点:
优点:
- 松耦合:观察者与主题之间是松散耦合的,主题并不需要了解具体观察者的实现。
 - 可扩展性:当需要添加新的观察者时,无需修改主题或其他观察者类,只需要创建新的观察者类并注册即可。
 - 广播通信:一个主题可以有多个观察者,可以轻松地向多个对象发送更新通知。
 
缺点:
- 通知开销:如果观察者非常多,或者主题的状态频繁变化时,可能会导致性能问题。
 - 未知依赖:如果观察者过多,或者观察者之间的依赖不明确,可能导致系统复杂度上升,出现不易察觉的错误。
 
观察者模式的应用场景:
- 事件处理:比如 GUI 程序中,用户点击按钮时,按钮触发事件,多个控件可能需要响应该事件。
 - 发布-订阅系统:例如消息队列系统,多个消费者监听同一个消息源。
 - MVC架构:模型(Model)就是主题,视图(View)就是观察者,当模型的状态改变时,视图会更新。
 
如果你有其他问题或具体的使用场景,欢迎继续提问!
发表回复