一、什么是观察者模式?
观察者模式(Observer Pattern)是一种行为型设计模式,用于对象之间的一对多依赖关系:当被观察对象(Subject)状态发生变化时,所有依赖它的观察者(Observer)都会自动收到通知并更新。
拿天气预报系统来类比
假设你是一个气象局的中央发布系统,每当你更新天气预报,订阅了你天气服务的各种渠道(如手机 App、LED 公交站牌、广播系统)都会自动收到通知并显示新的天气情况。
- 气象局 = 被观察者(Subject)
- 各种显示设备 = 观察者(Observer)
- 通知机制 = 观察者模式的核心精髓
二、模式结构图
三、代码实战
我们构建一个完整的天气通知系统:
WeatherStation
是被观察者PhoneDisplay
和LedBoardDisplay
是观察者
1. Observer 接口
public interface Observer {
void update(float temperature, float humidity, float pressure);
}
2. Subject 接口
public interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
3. WeatherStation(被观察者)
import java.util.ArrayList;
import java.util.List;
public class WeatherStation implements Subject {
private List<Observer> observers = new ArrayList<>();
private float temperature, humidity, pressure;
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
observers.remove(o);
}
@Override
public void notifyObservers() {
for (Observer o : observers) {
o.update(temperature, humidity, pressure);
}
}
public void setMeasurements(float temp, float hum, float press) {
this.temperature = temp;
this.humidity = hum;
this.pressure = press;
notifyObservers(); // 状态变了,通知大家!
}
}
4. 两个观察者实现类
手机显示端
public class PhoneDisplay implements Observer {
@Override
public void update(float temperature, float humidity, float pressure) {
System.out.println("[手机App] 当前天气:温度=" + temperature + "℃,湿度=" + humidity + "%,气压=" + pressure + " hPa");
}
}
LED 公交站牌
public class LedBoardDisplay implements Observer {
@Override
public void update(float temperature, float humidity, float pressure) {
System.out.println("[LED站牌] 实时天气:T=" + temperature + "℃ | H=" + humidity + "% | P=" + pressure + " hPa");
}
}
5. 主程序测试
public class WeatherApp {
public static void main(String[] args) {
WeatherStation station = new WeatherStation();
Observer phone = new PhoneDisplay();
Observer led = new LedBoardDisplay();
station.registerObserver(phone);
station.registerObserver(led);
station.setMeasurements(28.5f, 60f, 1012f);
station.setMeasurements(30.1f, 55f, 1008f);
}
}
四、实战示例UML 图
@startuml
interface Observer {
+update(temp, humidity, pressure)
}
interface Subject {
+registerObserver(o: Observer)
+removeObserver(o: Observer)
+notifyObservers()
}
class WeatherStation implements Subject {
-observers: List<Observer>
-temperature: float
-humidity: float
-pressure: float
+setMeasurements(temp, hum, press)
}
class PhoneDisplay implements Observer
class LedBoardDisplay implements Observer
Subject <|.. WeatherStation
Observer <|.. PhoneDisplay
Observer <|.. LedBoardDisplay
WeatherStation --> Observer : notifies >>
@enduml
五、优点与应用场景
优点
- 低耦合性:Subject 和 Observer 相互独立,只通过接口联系;
- 灵活可扩展:任意添加/删除观察者,不影响其他模块;
- 符合开闭原则:修改 Subject 不影响 Observer 行为。
典型应用场景
- GUI 事件系统(按钮点击监听)
- 消息订阅与发布(如 Kafka、MQTT)
- 数据驱动的响应式 UI 框架(React/Vue 背后的思想)
- 游戏状态监听器(如玩家血量变化通知 UI)
六、小结
一句话总结观察者模式: “我变了,我的订阅者们会立刻知道。”
观察者模式本质上是发布-订阅模式的一种实现。通过本篇“天气预报”类比,我们不仅理解了模式的结构,还体验了它在实际开发中的强大威力。