应用场景
- Kafka 消息订阅发布是吗?
- 邮件订阅
- RSS Feeds
原理
在对象之间定义一个一对多的依赖, 当一个对象状态改变的时候, 所有依赖的对象都会自动收到通知.
观察者模式的实现方法各式各样, 函数, 类的命名等会根据业务场景的不同有很大的差别, 比如 register 函数还可以叫作 attach, remove 函数还可以叫作 detach 等等. 不过, 万变不离其宗, 设计思路都是差不多的.
设计模式要干的事情就是解耦. 创建型模式是将创建和使用代码解耦, 结构型模式是将不同功能代码解耦, 行为型模式是将不同的行为代码解耦, 具体到观察者模式, 它是将观察者和被观察者代码解耦.
代码
#include <iostream> #include <vector> using namespace std; class Observer { public: virtual void update(float temp, float humidity, float pressure) = 0 {}; }; class Subject { public: virtual void registerObserver(Observer* o) = 0 {}; virtual void removeObserver(Observer* o) = 0 {}; virtual void notifyObservers() = 0 {}; }; class DisplayElement { public: virtual void display() = 0 {}; }; class WeatherData : public Subject { private: // 使用 vector 来记录观察者 vector<Observer*> observers; float temperature; float humidity; float pressure; public: WeatherData() { } void registerObserver(Observer* o) { observers.push_back(o); } void removeObserver(Observer* o) { if (observers.empty()) { return; } vector<Observer*>::const_iterator it; for (it = observers.begin(); it != observers.end();) { if (*it == o) { it = observers.erase(it); } else { ++it; } } } /// <summary> /// 通知各个观察者 /// </summary> void notifyObservers() { if (observers.empty()) { return; } // 通知各个观察者 for (auto it = observers.begin(); it != observers.end(); ++it) { (*it)->update(temperature, humidity, pressure); } } void messurementsChanged() { notifyObservers(); } void setMeasurements(float temperature, float humidity, float pressure) { this->temperature = temperature; this->humidity = humidity; this->pressure = pressure; messurementsChanged(); } }; class CurrentConditionsDisplay : public Observer, public DisplayElement { private: float temperature; float humidity; Subject* weatherData; public: /// <summary> /// 在构造方法中进行注册 /// </summary> /// <param name="weatherData"></param> CurrentConditionsDisplay(Subject* weatherData) { this->weatherData = weatherData; weatherData->registerObserver(this); } void update(float temperature, float humidity, float pressure) { this->temperature = temperature; this->humidity = humidity; display(); } void display() { cout << "Current conditions: " << temperature << "F degrees and " << humidity << "% humidity"; } }; int main() { WeatherData weatherData; CurrentConditionsDisplay currentDisplay(&weatherData); weatherData.setMeasurements(80, 65, 30.4f); return 0; }
本文链接地址:观察者模式,英雄不问来路,转载请注明出处,谢谢。
有话想说:那就赶紧去给我留言吧。
文章评论