第十三章:眼观六路,耳听八方——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 如何通过策略模式实现算法的灵活替换,且听下回分解!
更多推荐


所有评论(0)