观察者模式
行为型模式
访问次数: 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