但問題來了:

“運維小哥、監控系統、告警機器人、日誌中心……這麼多人關心同一件事,難道要一個個打電話通知?”

這時,一位神秘女子站在城市高塔之巔,輕輕按下腕錶——
全城警報同步響起!

她就是——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 的響應式數據(數據變 → 視圖自動更新)

⚠️ 注意事項

  1. 避免內存泄漏:觀察者用完記得 removeObserver()
    (否則對象無法被GC,就像“殭屍訂閲者”)
  2. 通知順序不可控:不要依賴觀察者執行順序!
  3. 線程安全:多線程環境下,需加鎖或使用 CopyOnWriteArrayList

🎯 總結:Watcher女俠的三大信條

  1. 鬆耦合:我不認識你,但我知道你在聽。
  2. 自動同步:狀態一變,全員知曉。
  3. 動態擴展:想加入?訂閲即可!想退出?退訂就行!