目录
1.介绍
观察者模式 是一种行为型模式 ,用于在对象之间定义一种一对多的依赖关系 ,
使得当一个对象的状态发生改变时,所有依赖它的对象都会自动收到通知并更新。
简单说:一个对象变化时,自动通知一群"订阅它"的对象。
2.角色
| 角色 | 职责 |
|---|---|
| Subject(主题/被观察者) | 持有观察者列表,提供注册、注销和通知的接口 |
| Observer(观察者接口) | 定义接收到通知时的回调接口 |
| ConcreteSubject(具体主题) | 实现主题逻辑(比如状态变化) |
| ConcreteObserver(具体观察者) | 实现更新逻辑,响应通知 |
3.代码例子
我们实现一个简单的场景:
当"天气"(WeatherStation)更新时,所有"显示屏"(Display)会自动刷新显示。
cpp
#include <iostream>
#include <vector>
#include <string>
#include <memory>
// 观察者接口
class Observer {
public:
virtual void update(float temperature, float humidity) = 0;
virtual ~Observer() = default;
};
// 被观察者(主题)接口
class Subject {
public:
virtual void attach(std::shared_ptr<Observer> obs) = 0;
virtual void detach(std::shared_ptr<Observer> obs) = 0;
virtual void notify() = 0;
virtual ~Subject() = default;
};
// 具体主题:天气站
class WeatherStation : public Subject {
private:
float temperature = 0.0f;
float humidity = 0.0f;
std::vector<std::shared_ptr<Observer>> observers;
public:
void setMeasurements(float t, float h) {
temperature = t;
humidity = h;
notify(); // 状态变化时通知观察者
}
void attach(std::shared_ptr<Observer> obs) override {
observers.push_back(obs);
}
void detach(std::shared_ptr<Observer> obs) override {
observers.erase(std::remove(observers.begin(), observers.end(), obs), observers.end());
}
void notify() override {
for (auto& obs : observers) {
obs->update(temperature, humidity);
}
}
};
// 具体观察者:显示屏
class Display : public Observer {
private:
std::string name;
public:
Display(const std::string& n) : name(n) {}
void update(float temperature, float humidity) override {
std::cout << "[" << name << "] "
<< "Temperature: " << temperature
<< "°C, Humidity: " << humidity << "%" << std::endl;
}
};
// 测试
int main() {
auto station = std::make_shared<WeatherStation>();
auto display1 = std::make_shared<Display>("Main Display");
auto display2 = std::make_shared<Display>("Outdoor Display");
station->attach(display1);
station->attach(display2);
station->setMeasurements(25.5f, 60.0f);
std::cout << "------ Weather Updated ------" << std::endl;
station->setMeasurements(30.2f, 55.0f);
return 0;
}
4.uml类图
