第十三章:眼观六路,耳听八方——Observer的观察艺术
第十三章:眼观六路,耳听八方——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 武功秘籍图
实战演练:高级观察者系统
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 如何通过策略模式实现算法的灵活替换,且听下回分解!