但問題來了:
“運維小哥、監控系統、告警機器人、日誌中心……這麼多人關心同一件事,難道要一個個打電話通知?”
這時,一位神秘女子站在城市高塔之巔,輕輕按下腕錶——
全城警報同步響起!
她就是——Watcher女俠!
💬 “我不主動找你,但只要你訂閲我,任何風吹草動,你立刻知道。”
📡 核心思想:一對多的依賴,自動通知!
- 被觀察者(Subject):事件源頭(如:服務器狀態)
- 觀察者(Observer):關心事件的人(如:運維、日誌、告警)
- 訂閲機制:觀察者主動註冊,被觀察者變化時自動廣播
🧪 場景演示:服務器温度監控系統
Step 1:定義“被觀察者”接口(Subject)
import java.util.*;
public interface ServerSubject {
void registerObserver(ServerObserver o);
void removeObserver(ServerObserver o);
void notifyObservers(); // 通知所有觀察者
}
Step 2:定義“觀察者”接口(Observer)
public interface ServerObserver {
void update(float temperature); // 接收通知
}
Step 3:實現被觀察者 —— 温度傳感器
public class TemperatureSensor implements ServerSubject {
private List<ServerObserver> observers = new ArrayList<>();
private float currentTemp;
public void setCurrentTemp(float temp) {
this.currentTemp = temp;
notifyObservers(); // 温度一變,立刻廣播!
}
@Override
public void registerObserver(ServerObserver o) {
observers.add(o);
}
@Override
public void notifyObservers() {
for (ServerObserver o : observers) {
o.update(currentTemp);
}
}
// ... removeObserver 略
}
Step 4:實現觀察者們!
// 運維小哥
public class DevOpsGuy implements ServerObserver {
public void update(float temp) {
if (temp > 80) {
System.out.println("🔥 運維小哥警報:服務器快燒了!温度:" + temp + "℃");
}
}
}
// 日誌系統
public class Logger implements ServerObserver {
public void update(float temp) {
System.out.println("📝 日誌記錄:當前温度 " + temp + "℃");
}
}
// 告警機器人
public class AlertBot implements ServerObserver {
public void update(float temp) {
if (temp > 90) {
System.out.println("🤖 告警機器人:啓動緊急冷卻!温度爆表:" + temp + "℃");
}
}
}
Step 5:啓動“消息廣播網”!
public class Main {
public static void main(String[] args) {
TemperatureSensor sensor = new TemperatureSensor();
// 所有人都來訂閲!
sensor.registerObserver(new DevOpsGuy());
sensor.registerObserver(new Logger());
sensor.registerObserver(new AlertBot());
// 模擬温度變化
sensor.setCurrentTemp(75); // 日誌記錄
sensor.setCurrentTemp(85); // 運維小哥警報
sensor.setCurrentTemp(95); // 機器人啓動冷卻!
}
}
✅ 輸出:
📝 日誌記錄:當前温度 75℃
🔥 運維小哥警報:服務器快燒了!温度:85℃
📝 日誌記錄:當前温度 85℃
🤖 告警機器人:啓動緊急冷卻!温度爆表:95℃
📝 日誌記錄:當前温度 95℃
🦸♀️ Watcher女俠的超能力解析
|
能力
|
對應設計原則
|
|
動態訂閲/退訂 |
解耦:被觀察者不知道具體觀察者是誰 |
|
自動廣播 |
推模型(Push):主動推送數據 |
|
一對多通知 |
支持任意數量觀察者,輕鬆擴展 |
💡 甚至支持 拉模型(Pull):只通知“有變化”,觀察者自己去拿數據!
🌐 現實中的“Watcher女俠”
- GUI事件監聽:按鈕點擊 → 觸發多個回調
- MQ消息隊列:生產者發消息,多個消費者訂閲
- Spring事件機制:
ApplicationEvent+@EventListener - 前端框架:Vue/React 的響應式數據(數據變 → 視圖自動更新)
⚠️ 注意事項
- 避免內存泄漏:觀察者用完記得
removeObserver()!
(否則對象無法被GC,就像“殭屍訂閲者”) - 通知順序不可控:不要依賴觀察者執行順序!
- 線程安全:多線程環境下,需加鎖或使用
CopyOnWriteArrayList
🎯 總結:Watcher女俠的三大信條
- 鬆耦合:我不認識你,但我知道你在聽。
- 自動同步:狀態一變,全員知曉。
- 動態擴展:想加入?訂閲即可!想退出?退訂就行!