第十三章:眼观六路,耳听八方——Observer的观察艺术

风云再起,观察者登场

在Proxy展示完他那精妙的访问控制艺术后,广场上众高手仍在回味不已。就在这时,一位眼观六路、耳听八方的哨兵般的人物,激动地从人群中跃出。

"Proxy兄的访问控制确实精妙!"Observer声音洪亮,眼中闪烁着兴奋的光芒,“但在对象状态变化时的通知机制方面,需要更加灵活的观察方式。诸位请看——”

Observer身形一晃,瞬间化作数个分身,每个分身都专注地监视着不同方向。他的声音在广场上回荡:“我的观察者模式,专为解决对象间的一对多依赖关系而生!当某个对象状态改变时,所有依赖它的对象都会自动得到通知并更新!”

架构老人抚须微笑:“善!Observer,就请你为大家展示这观察艺术的精妙所在。”

观察者模式的核心要义

Observer面向众人,开始阐述他的武学真谛:

“在我的观察者模式中,主要包含两个核心角色:”

Subject(主题):也就是被观察的对象,它维护着一个观察者列表,提供添加、删除和通知观察者的接口。”

Observer(观察者):定义了一个更新接口,当主题状态改变时会被调用。”

"其精妙之处在于,"Observer继续道,“主题与观察者之间是松耦合的。主题不知道观察者的具体实现,只知道它们实现了观察者接口。这样,我们可以随时增加新的观察者,而无需修改主题的代码!”

C++实战:气象监测系统

"且让我以一个气象监测系统为例,展示观察者模式的实战应用。"Observer说着,手中凝聚出一道道代码流光。

基础框架搭建

首先,Observer定义了观察者接口:

#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include <algorithm>
#include <map>
#include <iomanip>
#include <sstream>
#include <random>
#include <thread>
#include <chrono>

// 前向声明
class WeatherData;

// 观察者接口
class Observer {
public:
    virtual ~Observer() = default;
    virtual void update(float temperature, float humidity, float pressure) = 0;
    virtual void display() const = 0;
    virtual std::string getName() const = 0;
    
protected:
    WeatherData* weatherData_;
};

接着,他创建了主题接口:

// 主题接口
class Subject {
public:
    virtual ~Subject() = default;
    virtual void registerObserver(Observer* o) = 0;
    virtual void removeObserver(Observer* o) = 0;
    virtual void notifyObservers() = 0;
    virtual int getObserverCount() const = 0;
};

具体主题实现

Observer继续构建气象数据主题:

// 气象数据(具体主题)
class WeatherData : public Subject {
private:
    std::vector<Observer*> observers_;
    float temperature_;
    float humidity_;
    float pressure_;
    int updateCount_;
    std::string stationName_;
    
public:
    WeatherData(const std::string& name = "主气象站") 
        : temperature_(0.0f), humidity_(0.0f), pressure_(0.0f), 
          updateCount_(0), stationName_(name) {
        
        std::cout << "🌤️  创建气象站: " << stationName_ << std::endl;
    }
    
    ~WeatherData() {
        std::cout << "🗑️  销毁气象站: " << stationName_ << std::endl;
    }
    
    void registerObserver(Observer* o) override {
        observers_.push_back(o);
        std::cout << "✅ 注册观察者: " << o->getName() 
                  << " 到 " << stationName_ << std::endl;
    }
    
    void removeObserver(Observer* o) override {
        auto it = std::find(observers_.begin(), observers_.end(), o);
        if (it != observers_.end()) {
            observers_.erase(it);
            std::cout << "❌ 移除观察者: " << o->getName() 
                      << " 从 " << stationName_ << std::endl;
        }
    }
    
    void notifyObservers() override {
        std::cout << "📢 " << stationName_ << " 开始通知 " 
                  << observers_.size() << " 个观察者..." << std::endl;
        
        for (Observer* observer : observers_) {
            observer->update(temperature_, humidity_, pressure_);
        }
        
        updateCount_++;
        std::cout << "✅ 通知完成 (总更新次数: " << updateCount_ << ")" << std::endl;
    }
    
    void measurementsChanged() {
        std::cout << "\n🔔 " << stationName_ << " 数据更新!" << std::endl;
        std::cout << "   温度: " << temperature_ << "°C, "
                  << "湿度: " << humidity_ << "%, "
                  << "气压: " << pressure_ << "hPa" << std::endl;
        notifyObservers();
    }
    
    void setMeasurements(float temperature, float humidity, float pressure) {
        this->temperature_ = temperature;
        this->humidity_ = humidity;
        this->pressure_ = pressure;
        measurementsChanged();
    }
    
    // 模拟自动数据更新
    void generateRandomMeasurements() {
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_real_distribution<> tempDist(15.0, 35.0);
        std::uniform_real_distribution<> humidityDist(30.0, 90.0);
        std::uniform_real_distribution<> pressureDist(980.0, 1020.0);
        
        setMeasurements(tempDist(gen), humidityDist(gen), pressureDist(gen));
    }
    
    int getObserverCount() const override {
        return observers_.size();
    }
    
    std::string getStationInfo() const {
        std::stringstream ss;
        ss << "气象站: " << stationName_ 
           << " [观察者: " << observers_.size() 
           << ", 更新次数: " << updateCount_ << "]";
        return ss.str();
    }
    
    float getTemperature() const { return temperature_; }
    float getHumidity() const { return humidity_; }
    float getPressure() const { return pressure_; }
    std::string getStationName() const { return stationName_; }
};

具体观察者实现

Observer展示了各种不同类型的显示设备:

// 当前状况显示(具体观察者)
class CurrentConditionsDisplay : public Observer {
private:
    float temperature_;
    float humidity_;
    std::string displayName_;
    int updateCount_;
    
public:
    CurrentConditionsDisplay(WeatherData* weatherData, const std::string& name = "当前状况显示") 
        : temperature_(0.0f), humidity_(0.0f), displayName_(name), updateCount_(0) {
        
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "📊 创建 " << displayName_ << std::endl;
    }
    
    ~CurrentConditionsDisplay() {
        if (weatherData_) {
            weatherData_->removeObserver(this);
        }
        std::cout << "🗑️  销毁 " << displayName_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        this->temperature_ = temperature;
        this->humidity_ = humidity;
        updateCount_++;
        
        std::cout << "   🔄 " << displayName_ << " 收到更新 #" << updateCount_ << std::endl;
        display();
    }
    
    void display() const override {
        std::cout << "   📋 " << displayName_ << ": " 
                  << std::fixed << std::setprecision(1)
                  << temperature_ << "°C, " 
                  << humidity_ << "% 湿度" << std::endl;
    }
    
    std::string getName() const override {
        return displayName_;
    }
    
    std::string getDisplayInfo() const {
        std::stringstream ss;
        ss << displayName_ << " [更新次数: " << updateCount_ << "]";
        return ss.str();
    }
};

// 统计显示(具体观察者)
class StatisticsDisplay : public Observer {
private:
    float maxTemp_;
    float minTemp_;
    float tempSum_;
    int numReadings_;
    std::string displayName_;
    
public:
    StatisticsDisplay(WeatherData* weatherData, const std::string& name = "统计显示") 
        : maxTemp_(-100.0f), minTemp_(100.0f), tempSum_(0.0f), 
          numReadings_(0), displayName_(name) {
        
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "📈 创建 " << displayName_ << std::endl;
    }
    
    ~StatisticsDisplay() {
        if (weatherData_) {
            weatherData_->removeObserver(this);
        }
        std::cout << "🗑️  销毁 " << displayName_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        tempSum_ += temperature;
        numReadings_++;
        
        if (temperature > maxTemp_) {
            maxTemp_ = temperature;
        }
        
        if (temperature < minTemp_) {
            minTemp_ = temperature;
        }
        
        display();
    }
    
    void display() const override {
        if (numReadings_ > 0) {
            float avgTemp = tempSum_ / numReadings_;
            std::cout << "   📊 " << displayName_ << ": "
                      << "平均 " << std::fixed << std::setprecision(1) << avgTemp << "°C, "
                      << "最高 " << maxTemp_ << "°C, "
                      << "最低 " << minTemp_ << "°C" << std::endl;
        }
    }
    
    std::string getName() const override {
        return displayName_;
    }
    
    void resetStatistics() {
        maxTemp_ = -100.0f;
        minTemp_ = 100.0f;
        tempSum_ = 0.0f;
        numReadings_ = 0;
        std::cout << "🔄 重置 " << displayName_ << " 统计" << std::endl;
    }
};

// 天气预报显示(具体观察者)
class ForecastDisplay : public Observer {
private:
    float currentPressure_;
    float lastPressure_;
    std::string displayName_;
    
public:
    ForecastDisplay(WeatherData* weatherData, const std::string& name = "天气预报显示") 
        : currentPressure_(29.92f), lastPressure_(0.0f), displayName_(name) {
        
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "🔮 创建 " << displayName_ << std::endl;
    }
    
    ~ForecastDisplay() {
        if (weatherData_) {
            weatherData_->removeObserver(this);
        }
        std::cout << "🗑️  销毁 " << displayName_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        lastPressure_ = currentPressure_;
        currentPressure_ = pressure;
        display();
    }
    
    void display() const override {
        std::cout << "   🌈 " << displayName_ << ": ";
        if (currentPressure_ > lastPressure_) {
            std::cout << "天气将改善!" << std::endl;
        } else if (currentPressure_ == lastPressure_) {
            std::cout << "天气将保持不变" << std::endl;
        } else {
            std::cout << "天气将变差,可能下雨" << std::endl;
        }
    }
    
    std::string getName() const override {
        return displayName_;
    }
};

// 热指数显示(具体观察者)
class HeatIndexDisplay : public Observer {
private:
    float heatIndex_;
    std::string displayName_;
    
public:
    HeatIndexDisplay(WeatherData* weatherData, const std::string& name = "热指数显示") 
        : heatIndex_(0.0f), displayName_(name) {
        
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "🔥 创建 " << displayName_ << std::endl;
    }
    
    ~HeatIndexDisplay() {
        if (weatherData_) {
            weatherData_->removeObserver(this);
        }
        std::cout << "🗑️  销毁 " << displayName_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        heatIndex_ = computeHeatIndex(temperature, humidity);
        display();
    }
    
    void display() const override {
        std::cout << "   🌡️  " << displayName_ << ": "
                  << std::fixed << std::setprecision(1) << heatIndex_ << " (体感温度)" << std::endl;
    }
    
    std::string getName() const override {
        return displayName_;
    }
    
private:
    float computeHeatIndex(float t, float rh) const {
        // 简化的热指数计算公式
        return t + 0.5f * (t * rh / 100.0f);
    }
};

UML 武功秘籍图

notifies
observes
observes
observes
observes
«interface»
Subject
+registerObserver(Observer*) : void
+removeObserver(Observer*) : void
+notifyObservers() : void
+getObserverCount() : int
«interface»
Observer
+update(float, float, float) : void
+display() : void
+getName() : string
WeatherData
-vector<Observer*> observers_
-float temperature_
-float humidity_
-float pressure_
-int updateCount_
-string stationName_
+registerObserver(Observer*) : void
+removeObserver(Observer*) : void
+notifyObservers() : void
+setMeasurements(float, float, float) : void
+measurementsChanged() : void
+generateRandomMeasurements() : void
+getObserverCount() : int
+getStationInfo() : string
CurrentConditionsDisplay
-float temperature_
-float humidity_
-string displayName_
-int updateCount_
+update(float, float, float) : void
+display() : void
+getName() : string
+getDisplayInfo() : string
StatisticsDisplay
-float maxTemp_
-float minTemp_
-float tempSum_
-int numReadings_
-string displayName_
+update(float, float, float) : void
+display() : void
+getName() : string
+resetStatistics() : void
ForecastDisplay
-float currentPressure_
-float lastPressure_
-string displayName_
+update(float, float, float) : void
+display() : void
+getName() : string
HeatIndexDisplay
-float heatIndex_
-string displayName_
+update(float, float, float) : void
+display() : void
+getName() : string
-computeHeatIndex(float, float) : float

实战演练:高级观察者系统

Observer继续展示更复杂的观察者模式应用:

// 可配置的通用观察者
class ConfigurableDisplay : public Observer {
private:
    std::string displayName_;
    std::map<std::string, bool> displayOptions_;
    float lastTemperature_;
    float lastHumidity_;
    float lastPressure_;
    int updateCount_;
    
public:
    ConfigurableDisplay(WeatherData* weatherData, const std::string& name, 
                       const std::map<std::string, bool>& options = {})
        : displayName_(name), lastTemperature_(0.0f), lastHumidity_(0.0f), 
          lastPressure_(0.0f), updateCount_(0) {
        
        // 设置默认选项
        displayOptions_ = {
            {"show_temperature", true},
            {"show_humidity", true},
            {"show_pressure", true},
            {"show_trend", false},
            {"detailed_output", false}
        };
        
        // 合并用户选项
        for (const auto& option : options) {
            displayOptions_[option.first] = option.second;
        }
        
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "⚙️  创建可配置显示: " << displayName_ << std::endl;
    }
    
    ~ConfigurableDisplay() {
        if (weatherData_) {
            weatherData_->removeObserver(this);
        }
        std::cout << "🗑️  销毁可配置显示: " << displayName_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        lastTemperature_ = temperature;
        lastHumidity_ = humidity;
        lastPressure_ = pressure;
        updateCount_++;
        display();
    }
    
    void display() const override {
        std::cout << "   ⚙️  " << displayName_ << ":" << std::endl;
        
        if (displayOptions_.at("show_temperature")) {
            std::cout << "      🌡️  温度: " << std::fixed << std::setprecision(1) 
                      << lastTemperature_ << "°C" << std::endl;
        }
        
        if (displayOptions_.at("show_humidity")) {
            std::cout << "      💧 湿度: " << lastHumidity_ << "%" << std::endl;
        }
        
        if (displayOptions_.at("show_pressure")) {
            std::cout << "      🌀 气压: " << lastPressure_ << " hPa" << std::endl;
        }
        
        if (displayOptions_.at("detailed_output")) {
            std::cout << "      📈 更新次数: " << updateCount_ << std::endl;
        }
    }
    
    std::string getName() const override {
        return displayName_;
    }
    
    void setOption(const std::string& option, bool value) {
        if (displayOptions_.find(option) != displayOptions_.end()) {
            displayOptions_[option] = value;
            std::cout << "🔧 设置选项 " << option << " = " 
                      << (value ? "true" : "false") << std::endl;
        }
    }
    
    void showAllOptions() const {
        std::cout << "🔧 " << displayName_ << " 的配置选项:" << std::endl;
        for (const auto& option : displayOptions_) {
            std::cout << "   " << option.first << ": " 
                      << (option.second ? "✅" : "❌") << std::endl;
        }
    }
};

// 观察者管理器
class ObserverManager {
private:
    std::vector<std::unique_ptr<Observer>> observers_;
    WeatherData* weatherData_;
    
public:
    ObserverManager(WeatherData* weatherData) : weatherData_(weatherData) {
        std::cout << "👨‍💼 创建观察者管理器" << std::endl;
    }
    
    ~ObserverManager() {
        std::cout << "🗑️  销毁观察者管理器" << std::endl;
    }
    
    template<typename T, typename... Args>
    T* createObserver(const std::string& name, Args&&... args) {
        auto observer = std::make_unique<T>(weatherData_, name, std::forward<Args>(args)...);
        T* rawPtr = observer.get();
        observers_.push_back(std::move(observer));
        return rawPtr;
    }
    
    void removeObserver(const std::string& name) {
        auto it = std::find_if(observers_.begin(), observers_.end(),
            [&name](const std::unique_ptr<Observer>& observer) {
                return observer->getName() == name;
            });
            
        if (it != observers_.end()) {
            std::cout << "🗑️  从管理器移除观察者: " << name << std::endl;
            observers_.erase(it);
        }
    }
    
    void listObservers() const {
        std::cout << "\n📋 当前管理的观察者 (" << observers_.size() << " 个):" << std::endl;
        for (const auto& observer : observers_) {
            std::cout << "   • " << observer->getName() << std::endl;
        }
    }
    
    Observer* findObserver(const std::string& name) const {
        auto it = std::find_if(observers_.begin(), observers_.end(),
            [&name](const std::unique_ptr<Observer>& observer) {
                return observer->getName() == name;
            });
        return (it != observers_.end()) ? it->get() : nullptr;
    }
    
    size_t getObserverCount() const {
        return observers_.size();
    }
};

// 多气象站观察系统
class MultiStationWeatherSystem {
private:
    std::map<std::string, std::unique_ptr<WeatherData>> weatherStations_;
    std::map<std::string, std::unique_ptr<ObserverManager>> stationManagers_;
    
public:
    MultiStationWeatherSystem() {
        std::cout << "🌍 创建多气象站观察系统" << std::endl;
    }
    
    ~MultiStationWeatherSystem() {
        std::cout << "🗑️  销毁多气象站观察系统" << std::endl;
    }
    
    void addWeatherStation(const std::string& stationName) {
        auto station = std::make_unique<WeatherData>(stationName);
        auto manager = std::make_unique<ObserverManager>(station.get());
        
        weatherStations_[stationName] = std::move(station);
        stationManagers_[stationName] = std::move(manager);
        
        std::cout << "✅ 添加气象站: " << stationName << std::endl;
    }
    
    void removeWeatherStation(const std::string& stationName) {
        weatherStations_.erase(stationName);
        stationManagers_.erase(stationName);
        std::cout << "❌ 移除气象站: " << stationName << std::endl;
    }
    
    template<typename T, typename... Args>
    T* addObserverToStation(const std::string& stationName, const std::string& observerName, Args&&... args) {
        auto managerIt = stationManagers_.find(stationName);
        if (managerIt != stationManagers_.end()) {
            return managerIt->second->createObserver<T>(observerName, std::forward<Args>(args)...);
        }
        return nullptr;
    }
    
    void updateStationMeasurements(const std::string& stationName, 
                                  float temp, float humidity, float pressure) {
        auto stationIt = weatherStations_.find(stationName);
        if (stationIt != weatherStations_.end()) {
            stationIt->second->setMeasurements(temp, humidity, pressure);
        }
    }
    
    void generateRandomDataForAllStations() {
        std::cout << "\n🎲 为所有气象站生成随机数据..." << std::endl;
        for (auto& station : weatherStations_) {
            std::cout << "\n--- " << station.first << " ---" << std::endl;
            station.second->generateRandomMeasurements();
        }
    }
    
    void listAllStations() const {
        std::cout << "\n🏢 所有气象站 (" << weatherStations_.size() << " 个):" << std::endl;
        for (const auto& station : weatherStations_) {
            std::cout << "   📍 " << station.second->getStationInfo() << std::endl;
        }
    }
    
    WeatherData* getStation(const std::string& stationName) const {
        auto it = weatherStations_.find(stationName);
        return (it != weatherStations_.end()) ? it->second.get() : nullptr;
    }
    
    ObserverManager* getStationManager(const std::string& stationName) const {
        auto it = stationManagers_.find(stationName);
        return (it != stationManagers_.end()) ? it->second.get() : nullptr;
    }
};

观察者模式的招式解析

招式一:推模式与拉模式

Observer继续深入讲解:“在我的观察者模式中,有两种通知方式:”

// 推模式观察者:主题主动推送所有数据
class PushModeObserver : public Observer {
private:
    std::string name_;
    std::vector<std::tuple<float, float, float>> history_;
    
public:
    PushModeObserver(WeatherData* weatherData, const std::string& name) 
        : name_(name) {
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "📤 创建推模式观察者: " << name_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        history_.emplace_back(temperature, humidity, pressure);
        std::cout << "   📤 " << name_ << " 收到推送数据" << std::endl;
    }
    
    void display() const override {
        std::cout << "   📤 " << name_ << " 历史记录: " << history_.size() << " 条" << std::endl;
    }
    
    std::string getName() const override {
        return name_;
    }
};

// 拉模式观察者:观察者根据需要从主题拉取数据
class PullModeObserver : public Observer {
private:
    std::string name_;
    
public:
    PullModeObserver(WeatherData* weatherData, const std::string& name) 
        : name_(name) {
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "📥 创建拉模式观察者: " << name_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        // 在拉模式中,我们可能忽略推送的数据,自己从主题拉取
        std::cout << "   📥 " << name_ << " 选择拉取最新数据" << std::endl;
        if (weatherData_) {
            // 从主题拉取特定数据
            float currentTemp = weatherData_->getTemperature();
            std::cout << "      🌡️  当前温度: " << currentTemp << "°C" << std::endl;
        }
    }
    
    void display() const override {
        std::cout << "   📥 " << name_ << " (拉模式)" << std::endl;
    }
    
    std::string getName() const override {
        return name_;
    }
};

招式二:事件驱动的观察者

// 事件数据类
struct WeatherEvent {
    float temperature;
    float humidity;
    float pressure;
    std::chrono::system_clock::time_point timestamp;
    std::string stationName;
    std::string eventType;
    
    WeatherEvent(float t, float h, float p, const std::string& station, const std::string& type = "MEASUREMENT")
        : temperature(t), humidity(h), pressure(p), 
          timestamp(std::chrono::system_clock::now()),
          stationName(station), eventType(type) {}
    
    std::string toString() const {
        auto time = std::chrono::system_clock::to_time_t(timestamp);
        std::string timeStr = std::ctime(&time);
        timeStr.pop_back(); // 移除换行符
        
        std::stringstream ss;
        ss << "[" << timeStr << "] " << stationName << " " << eventType 
           << ": " << temperature << "°C, " << humidity << "%, " << pressure << "hPa";
        return ss.str();
    }
};

// 事件驱动的观察者
class EventDrivenObserver : public Observer {
private:
    std::string name_;
    std::vector<WeatherEvent> eventHistory_;
    int maxHistorySize_;
    
public:
    EventDrivenObserver(WeatherData* weatherData, const std::string& name, int maxHistory = 100) 
        : name_(name), maxHistorySize_(maxHistory) {
        this->weatherData_ = weatherData;
        weatherData->registerObserver(this);
        std::cout << "🎯 创建事件驱动观察者: " << name_ << std::endl;
    }
    
    void update(float temperature, float humidity, float pressure) override {
        if (weatherData_) {
            WeatherEvent event(temperature, humidity, pressure, 
                              weatherData_->getStationName());
            
            eventHistory_.push_back(event);
            
            // 保持历史记录大小
            if (eventHistory_.size() > maxHistorySize_) {
                eventHistory_.erase(eventHistory_.begin());
            }
            
            std::cout << "   🎯 " << name_ << " 记录事件 #" << eventHistory_.size() << std::endl;
        }
    }
    
    void display() const override {
        std::cout << "   🎯 " << name_ << " 事件历史 (" << eventHistory_.size() << " 个事件):" << std::endl;
        if (!eventHistory_.empty()) {
            std::cout << "      最新: " << eventHistory_.back().toString() << std::endl;
        }
    }
    
    std::string getName() const override {
        return name_;
    }
    
    void printEventHistory(int count = 5) const {
        int start = std::max(0, static_cast<int>(eventHistory_.size()) - count);
        std::cout << "\n📜 " << name_ << " 最近 " << (eventHistory_.size() - start) << " 个事件:" << std::endl;
        for (int i = start; i < eventHistory_.size(); ++i) {
            std::cout << "   " << eventHistory_[i].toString() << std::endl;
        }
    }
    
    void clearHistory() {
        eventHistory_.clear();
        std::cout << "🧹 清空 " << name_ << " 的事件历史" << std::endl;
    }
};

完整测试代码

// 测试观察者模式
void testObserverPattern() {
    std::cout << "=== 观察者模式测试开始 ===" << std::endl;
    
    // 创建气象站
    std::cout << "\n--- 基础观察者测试 ---" << std::endl;
    WeatherData weatherData("中央气象站");
    
    // 创建各种显示设备(观察者)
    CurrentConditionsDisplay currentDisplay(&weatherData, "主显示面板");
    StatisticsDisplay statsDisplay(&weatherData, "统计面板");
    ForecastDisplay forecastDisplay(&weatherData, "预报面板");
    HeatIndexDisplay heatIndexDisplay(&weatherData, "热指数面板");
    
    std::cout << "\n📊 初始观察者数量: " << weatherData.getObserverCount() << std::endl;
    
    // 模拟数据更新
    std::cout << "\n--- 第一次数据更新 ---" << std::endl;
    weatherData.setMeasurements(25.0f, 65.0f, 1013.0f);
    
    std::cout << "\n--- 第二次数据更新 ---" << std::endl;
    weatherData.setMeasurements(26.5f, 70.0f, 1012.5f);
    
    std::cout << "\n--- 第三次数据更新 ---" << std::endl;
    weatherData.setMeasurements(24.0f, 90.0f, 1010.0f);
    
    // 测试移除观察者
    std::cout << "\n--- 测试移除观察者 ---" << std::endl;
    {
        CurrentConditionsDisplay tempDisplay(&weatherData, "临时显示");
        std::cout << "📊 添加临时观察者后数量: " << weatherData.getObserverCount() << std::endl;
        weatherData.setMeasurements(23.0f, 80.0f, 1011.0f);
    } // tempDisplay 超出作用域,自动移除
    
    std::cout << "📊 临时观察者销毁后数量: " << weatherData.getObserverCount() << std::endl;
    
    // 测试可配置观察者
    std::cout << "\n--- 可配置观察者测试 ---" << std::endl;
    std::map<std::string, bool> configOptions = {
        {"show_temperature", true},
        {"show_humidity", false},  // 关闭湿度显示
        {"show_pressure", true},
        {"show_trend", true},
        {"detailed_output", true}
    };
    
    ConfigurableDisplay configDisplay(&weatherData, "配置显示", configOptions);
    weatherData.setMeasurements(22.0f, 75.0f, 1012.0f);
    
    // 修改配置
    std::cout << "\n--- 修改配置选项 ---" << std::endl;
    configDisplay.setOption("show_humidity", true); // 开启湿度显示
    configDisplay.showAllOptions();
    weatherData.setMeasurements(21.5f, 78.0f, 1011.5f);
    
    // 测试推模式和拉模式
    std::cout << "\n--- 推模式与拉模式测试 ---" << std::endl;
    PushModeObserver pushObserver(&weatherData, "推模式观察者");
    PullModeObserver pullObserver(&weatherData, "拉模式观察者");
    weatherData.setMeasurements(20.0f, 85.0f, 1010.0f);
    
    // 测试事件驱动观察者
    std::cout << "\n--- 事件驱动观察者测试 ---" << std::endl;
    EventDrivenObserver eventObserver(&weatherData, "事件记录器", 10);
    
    // 生成多次更新以填充历史
    for (int i = 0; i < 8; ++i) {
        weatherData.generateRandomMeasurements();
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    
    eventObserver.printEventHistory(3);
    
    std::cout << "\n=== 基础观察者模式测试结束 ===" << std::endl;
}

// 测试多气象站系统
void testMultiStationSystem() {
    std::cout << "\n=== 多气象站系统测试开始 ===" << std::endl;
    
    MultiStationWeatherSystem multiSystem;
    
    // 添加多个气象站
    multiSystem.addWeatherStation("北京气象站");
    multiSystem.addWeatherStation("上海气象站");
    multiSystem.addWeatherStation("广州气象站");
    multiSystem.addWeatherStation("成都气象站");
    
    // 为每个气象站添加观察者
    std::cout << "\n--- 为气象站添加观察者 ---" << std::endl;
    
    // 北京站
    multiSystem.addObserverToStation<CurrentConditionsDisplay>("北京气象站", "北京主显示");
    multiSystem.addObserverToStation<StatisticsDisplay>("北京气象站", "北京统计");
    
    // 上海站
    multiSystem.addObserverToStation<CurrentConditionsDisplay>("上海气象站", "上海主显示");
    multiSystem.addObserverToStation<ForecastDisplay>("上海气象站", "上海预报");
    
    // 广州站
    multiSystem.addObserverToStation<CurrentConditionsDisplay>("广州气象站", "广州主显示");
    multiSystem.addObserverToStation<HeatIndexDisplay>("广州气象站", "广州热指数");
    
    // 成都站
    auto configOptions = std::map<std::string, bool>{
        {"show_temperature", true},
        {"show_humidity", true},
        {"show_pressure", true},
        {"show_trend", true},
        {"detailed_output", true}
    };
    multiSystem.addObserverToStation<ConfigurableDisplay>("成都气象站", "成都配置显示", configOptions);
    
    // 列出所有气象站
    multiSystem.listAllStations();
    
    // 为各站更新数据
    std::cout << "\n--- 更新各站数据 ---" << std::endl;
    
    multiSystem.updateStationMeasurements("北京气象站", 18.5f, 45.0f, 1015.0f);
    multiSystem.updateStationMeasurements("上海气象站", 22.0f, 75.0f, 1012.0f);
    multiSystem.updateStationMeasurements("广州气象站", 28.5f, 85.0f, 1008.0f);
    multiSystem.updateStationMeasurements("成都气象站", 20.0f, 65.0f, 1013.0f);
    
    // 生成随机数据
    std::cout << "\n--- 生成随机数据测试 ---" << std::endl;
    multiSystem.generateRandomDataForAllStations();
    
    // 测试观察者管理器
    std::cout << "\n--- 测试观察者管理器 ---" << std::endl;
    auto beijingManager = multiSystem.getStationManager("北京气象站");
    if (beijingManager) {
        beijingManager->listObservers();
        
        // 动态添加新观察者
        std::cout << "\n--- 动态添加新观察者 ---" << std::endl;
        beijingManager->createObserver<EventDrivenObserver>("北京事件记录器");
        
        // 再次更新数据
        multiSystem.updateStationMeasurements("北京气象站", 19.0f, 50.0f, 1014.0f);
        
        beijingManager->listObservers();
    }
    
    std::cout << "\n=== 多气象站系统测试结束 ===" << std::endl;
}

// 实战应用:智能气象监控系统
class SmartWeatherMonitoringSystem {
private:
    MultiStationWeatherSystem multiSystem_;
    bool isRunning_;
    
public:
    SmartWeatherMonitoringSystem() : isRunning_(false) {
        std::cout << "🚀 智能气象监控系统启动" << std::endl;
        initializeSystem();
    }
    
    ~SmartWeatherMonitoringSystem() {
        stop();
        std::cout << "🛑 智能气象监控系统关闭" << std::endl;
    }
    
    void initializeSystem() {
        // 初始化气象站
        std::vector<std::string> stations = {
            "华北气象站", "华东气象站", "华南气象站", 
            "华西气象站", "华中气象站"
        };
        
        for (const auto& station : stations) {
            multiSystem_.addWeatherStation(station);
            
            // 为每个站添加标准观察者
            multiSystem_.addObserverToStation<CurrentConditionsDisplay>(station, station + "-主显示");
            multiSystem_.addObserverToStation<StatisticsDisplay>(station, station + "-统计");
            multiSystem_.addObserverToStation<EventDrivenObserver>(station, station + "-事件记录");
        }
        
        std::cout << "✅ 系统初始化完成,共 " << stations.size() << " 个气象站" << std::endl;
    }
    
    void start() {
        isRunning_ = true;
        std::cout << "🎬 开始气象数据监控..." << std::endl;
        
        // 模拟实时数据更新
        std::thread updateThread([this]() {
            std::random_device rd;
            std::mt19937 gen(rd());
            std::uniform_int_distribution<> intervalDist(1000, 3000); // 1-3秒间隔
            
            while (isRunning_) {
                // 为随机站点生成数据
                multiSystem_.generateRandomDataForAllStations();
                
                // 随机间隔
                int interval = intervalDist(gen);
                std::this_thread::sleep_for(std::chrono::milliseconds(interval));
            }
        });
        
        updateThread.detach();
    }
    
    void stop() {
        isRunning_ = false;
        std::cout << "⏹️  停止气象数据监控" << std::endl;
    }
    
    void showSystemStatus() {
        std::cout << "\n📊 智能气象监控系统状态" << std::endl;
        std::cout << "======================" << std::endl;
        multiSystem_.listAllStations();
    }
    
    void addCustomStation(const std::string& stationName) {
        multiSystem_.addWeatherStation(stationName);
        
        // 为新站添加观察者
        multiSystem_.addObserverToStation<CurrentConditionsDisplay>(stationName, stationName + "-显示");
        multiSystem_.addObserverToStation<ConfigurableDisplay>(stationName, stationName + "-配置显示");
        
        std::cout << "✅ 添加自定义气象站: " << stationName << std::endl;
    }
    
    void runDemo() {
        std::cout << "\n🎮 运行演示模式..." << std::endl;
        std::cout << "==================" << std::endl;
        
        start();
        
        // 让系统运行一段时间
        std::this_thread::sleep_for(std::chrono::seconds(10));
        
        stop();
        
        std::cout << "\n📈 演示模式结束" << std::endl;
        showSystemStatus();
    }
};

int main() {
    std::cout << "🌈 设计模式武林大会 - 观察者模式演示 🌈" << std::endl;
    std::cout << "=====================================" << std::endl;
    
    // 测试基础观察者模式
    testObserverPattern();
    
    // 测试多气象站系统
    testMultiStationSystem();
    
    // 运行智能气象监控系统演示
    std::cout << "\n=== 智能气象监控系统演示 ===" << std::endl;
    SmartWeatherMonitoringSystem smartSystem;
    smartSystem.runDemo();
    
    // 交互式演示
    std::cout << "\n🎯 交互式演示" << std::endl;
    std::cout << "============" << std::endl;
    
    WeatherData demoStation("演示气象站");
    ObserverManager demoManager(&demoStation);
    
    demoManager.createObserver<CurrentConditionsDisplay>("演示显示1");
    demoManager.createObserver<StatisticsDisplay>("演示统计");
    demoManager.createObserver<ForecastDisplay>("演示预报");
    
    std::cout << "\n🔄 模拟实时数据流..." << std::endl;
    for (int i = 0; i < 5; ++i) {
        demoStation.generateRandomMeasurements();
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    
    demoManager.listObservers();
    
    std::cout << "\n🎉 观察者模式演示全部完成!" << std::endl;
    
    return 0;
}

观察者模式的武学心得

适用场景

  • 一对多依赖关系:当一个对象状态改变需要通知其他多个对象时
  • 事件处理系统:需要实现事件发布-订阅机制时
  • 用户界面更新:当数据模型改变需要更新多个视图时
  • 分布式系统:在消息传递和事件驱动的架构中

优点

  • 松耦合:主题和观察者之间抽象耦合,彼此不知道对方的具体实现
  • 开闭原则:可以轻松增加新的观察者,无需修改主题
  • 广播通信:支持一对多的通信方式
  • 动态关系:可以在运行时建立和解除观察关系

缺点

  • 更新效率:如果观察者数量很多,通知所有观察者可能较慢
  • 循环依赖:不恰当的实现可能导致循环调用
  • 更新顺序:观察者的更新顺序可能影响系统行为
  • 内存泄漏:需要小心处理观察者的生命周期

武林高手的点评

Strategy 赞叹道:“Observer 兄的通知机制确实精妙!能够如此优雅地处理对象间的依赖关系,这在事件驱动系统中确实无人能及。”

Command 也点头称赞:“Observer 兄专注于状态变化的传播,而我更关注请求的封装和执行。我们都涉及对象间的通信,但关注点不同。”

Observer 谦虚回应:“诸位过奖了。每个模式都有其适用场景。在需要实现松耦合的通知机制时,我的观察者模式确实能发挥重要作用。但在需要封装操作请求时,Command 兄的方法更加合适。”

下章预告

在Observer展示完他那精妙的观察艺术后,Strategy 身背多种兵器,从容不迫地走出。

“Observer 兄的通知机制确实精妙,但在算法选择和策略切换方面,需要更加灵活的应对方式。” Strategy 沉稳地说道,“下一章,我将展示如何通过策略模式定义一系列可互换的算法,让客户端能够在运行时灵活选择不同的策略!”

架构老人满意地点头:“善!算法的灵活替换确实是应对变化的关键。下一章,就请 Strategy 展示他的策略艺术!”


欲知 Strategy 如何通过策略模式实现算法的灵活替换,且听下回分解!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐