观察者模式 (Observer Pattern)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
基础组件
- Subject (主题):被观察的对象,维护观察者列表
- Observer (观察者):定义更新接口
- ConcreteSubject (具体主题):存储状态,状态改变时通知观察者
- ConcreteObserver (具体观察者):实现更新接口
继承/实现关系
Subject <|-- ConcreteSubject
Observer <|-- ConcreteObserver
ConcreteSubject --> Observer (通知观察者)
应用场景
- 需要将对象状态变化通知给其他对象
- 一个对象改变需要改变其他对象,但不知道具体有多少对象需要改变
- 跨系统事件通知
C++ 实现(气象站数据发布)
#include <iostream>
#include <memory>
#include <string>
#include <vector>
/*
* 观察者模式
* 意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
* 基础组件:
* - Subject (主题):被观察的对象,维护观察者列表
* - Observer (观察者):定义更新接口
* - ConcreteSubject (具体主题):存储状态,状态改变时通知观察者
* - ConcreteObserver (具体观察者):实现更新接口
* 继承/实现关系:
* ConcreteSubject 继承自 Subject,ConcreteObserver 实现 Observer 接口。
* ConcreteSubject 维护一个观察者列表,并在状态改变时调用每个观察者的更新方法。
*/
// 观察者接口
class Observer {
public:
virtual ~Observer() = default;
virtual void update(float temperature, float humidity) = 0;
};
// 主题接口
class Subject {
public:
virtual void registerObserver(std::shared_ptr<Observer> o) = 0;
virtual void removeObserver(std::shared_ptr<Observer> o) = 0;
virtual void notifyObservers() = 0;
};
// 具体主题:气象站,提供注册、移除观察者和通知观察者的功能
class WeatherStation : public Subject {
public:
void registerObserver(std::shared_ptr<Observer> o) override {
observers_.push_back(o);
}
void removeObserver(std::shared_ptr<Observer> o) override {
auto it = std::find(observers_.begin(), observers_.end(), o);
if (it != observers_.end()) {
observers_.erase(it);
}
}
void notifyObservers() override {
// 具体主题负责通知所有注册的观察者
for (auto& o : observers_) {
o->update(temperature_, humidity_);
}
}
// 气象数据更新时调用
void setMeasurements(float temperature, float humidity) {
temperature_ = temperature;
humidity_ = humidity;
// 通知所有观察者
notifyObservers();
}
private:
std::vector<std::shared_ptr<Observer>> observers_;
float temperature_ = 0.0f;
float humidity_ = 0.0f;
};
// 具体观察者:显示当前天气,提供一个update方法来接收主题的状态更新
class CurrentConditionsDisplay : public Observer {
public:
void update(float temperature, float humidity) override {
temperature_ = temperature;
humidity_ = humidity;
display();
}
void display() const {
std::cout << "Current conditions: " << temperature_
<< "°C and " << humidity_ << "% humidity\n";
}
private:
float temperature_;
float humidity_;
};
// 具体观察者:天气统计
class StatisticsDisplay : public Observer {
public:
void update(float temperature, float humidity) override {
// 更新统计信息(这里简化)
maxTemp_ = std::max(maxTemp_, temperature);
minTemp_ = std::min(minTemp_, temperature);
display();
}
void display() const {
std::cout << "Weather stats: Max=" << maxTemp_
<< "°C, Min=" << minTemp_ << "°C\n";
}
private:
float maxTemp_ = -100.0f;
float minTemp_ = 100.0f;
};
void ObserverPattern()
{
std::cout << std::string(13, '-') << " Observer Pattern " << std::string(13, '-') << std::endl;
auto weatherStation = std::make_shared<WeatherStation>();
auto currentDisplay = std::make_shared<CurrentConditionsDisplay>();
auto statsDisplay = std::make_shared<StatisticsDisplay>();
weatherStation->registerObserver(currentDisplay);
weatherStation->registerObserver(statsDisplay);
// 更新气象数据
weatherStation->setMeasurements(25.0f, 65.0f);
weatherStation->setMeasurements(27.5f, 70.0f);
weatherStation->setMeasurements(26.8f, 80.0f);
// 移除一个观察者
weatherStation->removeObserver(statsDisplay);
weatherStation->setMeasurements(22.3f, 75.0f);
}
组件对应关系
Subject→ 主题接口WeatherStation→ 具体主题Observer→ 观察者接口CurrentConditionsDisplay/StatisticsDisplay→ 具体观察者
1279

被折叠的 条评论
为什么被折叠?



