C++二十三种设计模式之观察者模式
一、组成
抽象主题 :维护观察者对象列表,具备通知功能。
具体主题 :实现维护观察者对象列表具体策略和通知功能。
抽象观察者 :为主题类提供更新接口。
具体观察者:实现更新接口。
二、目的
用于一个对象状态发生变化,所有依赖于它的对象都自动收到通知并进行更新。
三、缺点
1、资源浪费问题,存在大量观察者时,通知所有观察者会导致不需要此消息的观察者也收到这个消息。
2、通知顺序不确定,如果观察者之间需要存在先后收到通知的依赖关系时会有问题、
四、示例代码
javascript
#include<iostream>
#include <vector>
#include <string>
using namespace std;
class WeatherObserver;//抽象观察者类
class WeatherApp;//具体观察者类
class AbstractWeatherStation;//抽象主题类
class WeatherStation;//具体主题类
class WeatherObserver {
public:
virtual void updateWeather(const string weatherName) = 0;
};
class WeatherApp :public WeatherObserver {
public:
explicit WeatherApp(const string appName) :appName(appName) {};
void updateWeather(const string weatherName) {
weatherCur = weatherName;
printCurWeather();
}
void printCurWeather() {
cout << "The current weather on thre " << appName << " app is " << weatherCur << endl;
}
private:
string weatherCur;
string appName;
};
class AbstractWeatherStation {
public:
virtual void addObserver(shared_ptr<WeatherObserver> observer) = 0;
virtual void removeObserver(shared_ptr<WeatherObserver> observer) = 0;
virtual void notifyObservers() = 0;
protected:
vector<shared_ptr<WeatherObserver>> observers;
};
class WeatherStation :public AbstractWeatherStation {
public:
void addObserver(shared_ptr<WeatherObserver> observer) {
observers.push_back(observer);
}
void removeObserver(shared_ptr<WeatherObserver> observer) {
observers.erase(remove(observers.begin(), observers.end(), observer), observers.end());
}
void notifyObservers() {
for (const auto& observer : observers) {
observer->updateWeather(weatherCur);
}
}
void updateWeather(const string& weather) {
weatherCur = weather;
notifyObservers();
}
private:
vector<shared_ptr<WeatherObserver>> observers;
string weatherCur;
};
int main() {
shared_ptr<WeatherObserver> app1 = make_shared<WeatherApp>("天气宝app");
shared_ptr<WeatherObserver> app2 = make_shared<WeatherApp>("气象通app");
shared_ptr<WeatherStation> weatherStation = make_shared<WeatherStation>();
weatherStation->addObserver(app1);
weatherStation->addObserver(app2);
weatherStation->updateWeather("晴天");
weatherStation->removeObserver(app1);
weatherStation->updateWeather("雨天");
}