文章目录
行为型模式:观察者模式
观察者模式定义了一种一对多的依赖关系:它让一个主题(被观察者)对象关联多个观察者对象,并且当主题对象的状态发生变化时,它会主动通知这些观察者对象,使它们能够自动更新自己或执行相应的响应操作。
以一个设备的温度显示系统为例,在这个示例中,温度检测仪是被观察者,当设备温度发生变化时,它会通知所有的显示器更新温度信息。
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
// 观察者接口
class IObserver {
public:
virtual void update(float temperature) = 0;
virtual ~IObserver() {}
};
// 主题接口(Subject)
class ISubject {
public:
virtual void registerObserver(IObserver* observer) = 0;
virtual void removeObserver(IObserver* observer) = 0;
virtual void notifyObservers() = 0;
virtual ~ISubject() {}
};
// 被观察者类:设备温度检测仪
class DeviceTemperatureMonitor : public ISubject {
private:
std::vector<IObserver*> observers;
float temperature;
public:
// 注册观察者
void registerObserver(IObserver* observer) override {
observers.push_back(observer);
}
// 移除观察者
void removeObserver(IObserver* observer) override {
// std::remove将所有与指定值observer相等的元素移动到容器的末尾,并返回指向第一个不需要保留的元素的迭代器
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
// 通知所有观察者
void notifyObservers() override {
for (IObserver* observer : observers) {
observer->update(temperature);
}
}
// 设置温度状态并通知所有观察者
void setTemperature(float temp) {
temperature = temp;
notifyObservers();
}
};
// 观察者类:手机显示器
class PhoneDisplay : public IObserver {
private:
std::string deviceName;
public:
PhoneDisplay(const std::string& name) : deviceName(name) {}
void update(float temperature) override {
std::cout << "Phone Display (" << deviceName << ") - Device Temperature: "
<< temperature << "°C\n";
}
};
// 观察者类:窗口显示器
class WindowDisplay : public IObserver {
private:
std::string location;
public:
WindowDisplay(const std::string& loc) : location(loc) {}
void update(float temperature) override {
std::cout << "Window Display at " << location << " - Device Temperature: "
<< temperature << "°C\n";
}
};
int main() {
// 创建被观察者对象(设备温度检测仪)
DeviceTemperatureMonitor tempMonitor;
// 创建观察者对象(显示设备)
PhoneDisplay phoneDisplay1("iPhone");
PhoneDisplay phoneDisplay2("Samsung");
WindowDisplay windowDisplay("Office");
// 注册观察者
tempMonitor.registerObserver(&phoneDisplay1);
tempMonitor.registerObserver(&phoneDisplay2);
tempMonitor.registerObserver(&windowDisplay);
// 模拟温度数据更新
std::cout << "Temperature Update 1:\n";
tempMonitor.setTemperature(75.0f);
std::cout << "\nTemperature Update 2:\n";
tempMonitor.setTemperature(80.0f);
// 移除一个观察者
tempMonitor.removeObserver(&phoneDisplay2);
std::cout << "\nTemperature Update 3 (After removing Samsung Phone Display):\n";
tempMonitor.setTemperature(85.0f);
return 0;
}
Temperature Update 1:
Phone Display (iPhone) - Device Temperature: 75°C
Phone Display (Samsung) - Device Temperature: 75°C
Window Display at Office - Device Temperature: 75°C
Temperature Update 2:
Phone Display (iPhone) - Device Temperature: 80°C
Phone Display (Samsung) - Device Temperature: 80°C
Window Display at Office - Device Temperature: 80°C
Temperature Update 3 (After removing Samsung Phone Display):
Phone Display (iPhone) - Device Temperature: 85°C
Window Display at Office - Device Temperature: 85°C