3.观察者模式(Observer Pattern)
·
观察者模式定义
观察者模式是一种行为型设计模式,用于在对象之间建立一对多依赖关系。当一个对象(称为Subject,主题)的状态发生改变时,所有依赖它的对象(称为Observer,观察者)会自动收到通知并更新。该模式的核心是解耦主题与观察者,避免直接依赖。
适用场景
1.事件驱动系统:
- 如用户界面按钮点击事件、游戏中的成就系统。
2.状态同步需求:
- 例如天气预报系统通知多个显示设备更新数据。
3.跨模块通信:
- 订单状态变化时通知库存系统、支付系统等。
4.避免轮询检查:
- 用推送机制代替观察者主动轮询主题状态。
代码示例
未使用观察者模式的代码
以下是一个简单的温度监控系统,直接硬编码通知逻辑:
#include <iostream>
#include <vector>
// 温度传感器(主题)
class TemperatureSensor {
private:
float temperature;
std::vector<class Display*> displays; // 硬编码依赖具体显示设备
public:
void setTemperature(float temp) {
temperature = temp;
// 直接调用所有显示设备的更新方法
for (auto display : displays) {
display->update(temperature);
}
}
void addDisplay(Display* display) {
displays.push_back(display);
}
};
// 显示设备(观察者)
class Display {
public:
void update(float temp) {
std::cout << "当前温度: " << temp << "°C" << std::endl;
}
};
int main() {
TemperatureSensor sensor;
Display display1, display2;
sensor.addDisplay(&display1);
sensor.addDisplay(&display2);
sensor.setTemperature(25.5); // 输出两次温度信息
return 0;
}
使用观察者模式优化
通过抽象接口和动态注册机制解耦主题与观察者:
#include <iostream>
#include <vector>
#include <memory>
// 观察者接口(抽象层)
class IObserver {
public:
virtual ~IObserver() = default;
virtual void update(float temperature) = 0; // 统一更新方法
};
// 主题接口(抽象层)
class ISubject {
public:
virtual ~ISubject() = default;
virtual void registerObserver(std::shared_ptr<IObserver> observer) = 0;
virtual void notifyObservers() = 0;
};
// 具体主题:温度传感器
class TemperatureSensor : public ISubject {
private:
float temperature;
std::vector<std::shared_ptr<IObserver>> observers; // 观察者列表
public:
void setTemperature(float temp) {
temperature = temp;
notifyObservers(); // 通知所有观察者
}
void registerObserver(std::shared_ptr<IObserver> observer) override {
observers.push_back(observer);
}
void notifyObservers() override {
for (auto& observer : observers) {
observer->update(temperature);
}
}
};
// 具体观察者:显示屏
class Display : public IObserver {
public:
void update(float temperature) override {
std::cout << "显示屏更新 -> 温度: " << temperature << "°C" << std::endl;
}
};
// 具体观察者:手机通知(新增观察者类型)
class PhoneNotification : public IObserver {
public:
void update(float temperature) override {
std::cout << "手机通知: 当前温度 " << temperature << "°C" << std::endl;
}
};
int main() {
// 创建主题和观察者
auto sensor = std::make_shared<TemperatureSensor>();
auto display = std::make_shared<Display>();
auto phone = std::make_shared<PhoneNotification>();
// 注册观察者
sensor->registerObserver(display);
sensor->registerObserver(phone);
// 温度变化触发通知
sensor->setTemperature(25.5);
/* 输出:
显示屏更新 -> 温度: 25.5°C
手机通知: 当前温度 25.5°C
*/
return 0;
}
代码注释:
IObserver 接口:定义统一的 update 方法,所有观察者必须实现。
ISubject 接口:提供注册和通知观察者的方法,主题类(如 TemperatureSensor)实现该接口。
动态注册机制:通过 registerObserver 动态添加观察者,无需修改主题代码。
解耦设计:主题仅依赖 IObserver 接口,不关心具体观察者类型。
模式优势
松耦合:主题和观察者通过接口交互,互不依赖具体实现。
扩展性:新增观察者类型无需修改主题代码(如添加 EmailNotification)。
事件驱动:支持广播通知,避免轮询资源浪费。
符合开闭原则:主题和观察者可以独立扩展。
更多推荐



所有评论(0)