观察者模式

行为型模式

访问次数: 11

观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

类图
classDiagram
    class Subject {
        <<interface>>
        +attach(observer: Observer)
        +detach(observer: Observer)
        +notify()
    }
    class ConcreteSubject {
        -observers: List~Observer~
        -state: String
        +attach(observer: Observer)
        +detach(observer: Observer)
        +notify()
        +setState(state: String)
    }
    class Observer {
        <<interface>>
        +update(subject: Subject)
    }
    class ConcreteObserverA {
        +update(subject: Subject)
    }
    class ConcreteObserverB {
        +update(subject: Subject)
    }
    Subject <|-- ConcreteSubject
    Observer <|-- ConcreteObserverA
    Observer <|-- ConcreteObserverB
    ConcreteSubject --> Observer
源代码示例
// 主题接口
interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notify();
}

// 观察者接口
interface Observer {
    void update(Subject subject);
}

// 具体主题
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;
    
    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notify() {
        for (Observer observer : observers) {
            observer.update(this);
        }
    }
    
    public void setState(String state) {
        this.state = state;
        notify();
    }
    
    public String getState() {
        return state;
    }
}

// 具体观察者A
class ConcreteObserverA implements Observer {
    @Override
    public void update(Subject subject) {
        System.out.println("ObserverA received update: " + ((ConcreteSubject) subject).getState());
    }
}

// 具体观察者B
class ConcreteObserverB implements Observer {
    @Override
    public void update(Subject subject) {
        System.out.println("ObserverB received update: " + ((ConcreteSubject) subject).getState());
    }
}
# Python代码待添加
应用场景
当一个对象的改变需要同时改变其他对象,且不知道有多少对象需要改变时。应用场景包括: 1)股票价格变化时,需要通知所有关注该股票的投资者 2)MVC架构中,模型数据变化时需要通知所有相关的视图进行更新 3)事件驱动系统,当事件发生时需要通知所有注册的事件处理器 4)发布-订阅系统,当消息发布时需要通知所有订阅者 5)游戏引擎中,当游戏状态变化时需要通知所有相关的游戏对象和UI组件 6)配置管理系统,当配置参数变化时需要通知所有使用该配置的组件进行更新
精选场景详解 —— 股票行情:价格变动通知投资者
问题背景

股价一变,要通知 App 自选列表、邮件提醒、量化策略等多个观察者。股票对象不应硬编码这些依赖,观察者集合也会动态增减。

模式如何解决
选用观察者模式:Stock(Subject)维护 Observer 列表,提供 attach/detach/notify;价格 setPrice 时 notify。InvestorApp、MailAlerter 等实现 update。 特点:一对多依赖,松耦合,支持广播。发布-订阅、GUI 事件监听、MVC 中模型通知视图都属此族。 注意:通知顺序、异常隔离、以及观察者里勿再同步触发复杂链路造成级联风暴;高吞吐行情系统可引入消息队列做异步解耦。
场景模型(角色映射)

将模式中的抽象角色映射到该业务领域的具体类:

classDiagram
    class Stock {
        -symbol: String
        -price: decimal
        -observers: List~InvestorObserver~
        +attach(o: InvestorObserver)
        +detach(o: InvestorObserver)
        +notify()
        +setPrice(price: decimal)
    }
    class InvestorObserver {
        <<interface>>
        +update(stock: Stock)
    }
    class MobileAppObserver {
        +update(stock: Stock)
    }
    class MailAlertObserver {
        +update(stock: Stock)
    }
    class QuantStrategyObserver {
        +update(stock: Stock)
    }
    InvestorObserver <|.. MobileAppObserver
    InvestorObserver <|.. MailAlertObserver
    InvestorObserver <|.. QuantStrategyObserver
    Stock --> InvestorObserver