设计模式最大的作用就是在变化和稳定中间寻找隔离点,然后分离它们,从而管理变化。将变化像小兔子一样关到笼子里,让它在笼子里随便跳,而不至于跳出来把你整个房间给污染掉。
设计思想
主题对象(出版者)管理某些数据,当主题内的数据改变,就会通知观察者(订阅者)。
观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。相比让多个对象控制同一份数据,可以得到更干净的OO设计。文章来源:https://www.toymoban.com/news/detail-692454.html
业务场景
假定现在有一个气象站类,这个气象站类会不定时更新温度,湿度,气压的最新数据,要求你在这些数值变化时,立即通知一些气象局进行展示,而他们得到的数据是一样的,但是采用的展示手段可能是不一样的,比如有的采用图示,有的采用文字,有的采用语音播报等,给出设计代码。文章来源地址https://www.toymoban.com/news/detail-692454.html
代码案例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 观察者抽象类
class Observer
{
public:
virtual void update(const float tmp, const float hum, const float pre) = 0;
virtual ~Observer() {}
};
// 展示抽象类
class Display
{
public:
virtual void display() const = 0;
virtual ~Display() {}
};
// 主题抽象类
class Subject
{
public:
virtual void registerObserver(Observer* b) = 0;
virtual void removeObserver(Observer* b) = 0;
virtual void notifyObserver() const = 0;
virtual ~Subject() {}
};
class WeatherData : public Subject
{
private:
std::vector<Observer*> observers;
float temperature = 0;
float humidity = 0;
float pressure = 0;
public:
WeatherData() : Subject() {}
void registerObserver(Observer* b)
{
observers.push_back(b);
}
void removeObserver(Observer* ob)
{
auto it = find(observers.begin(), observers.end(), ob);
if (it != observers.end())
{
observers.erase(it);
}
}
// 通知观察者,使得所有观察者更新信息。
void notifyObserver() const
{
for (auto& it : observers)
{
it->update(temperature, humidity, pressure);
}
}
void measurementsChanged()
{
notifyObserver();
}
// 设置气象站天气信息并通知观察者。
void setMeasurements(const float tmp, const float hum, const float pre)
{
temperature = tmp;
humidity = hum;
pressure = pre;
measurementsChanged();
}
~WeatherData()
{
for (auto& each : observers)
{
delete each;
each = nullptr;
}
}
};
class CurrentConditionsDisplay : public Observer, public Display
{
private:
float temperature = 0;
float humidity = 0;
Subject* weatherData = nullptr;
public:
// 初始化信息板,并在气象站对其登记。
CurrentConditionsDisplay(Subject* wd) : Observer(), Display()
{
weatherData = wd;
weatherData->registerObserver(this);
}
// 更新天气信息并展示。
void update(const float tmp, const float hum, const float pre)
{
temperature = tmp;
humidity = hum;
display();
}
void display() const
{
cout << "气象局1: 当前温度:" << temperature << ", 当前湿度:" << humidity << endl;
}
~CurrentConditionsDisplay()
{
if (weatherData)
{
delete weatherData;
weatherData = nullptr;
}
}
};
class CurrentConditionsDisplay2 : public Observer, public Display
{
private:
float temperature = 0;
float humidity = 0;
Subject* weatherData = nullptr;
public:
// 初始化信息板,并在气象站对其登记。
CurrentConditionsDisplay2(Subject* wd) : Observer(), Display()
{
weatherData = wd;
weatherData->registerObserver(this);
}
// 更新天气信息并展示。
void update(const float tmp, const float hum, const float pre)
{
temperature = tmp;
humidity = hum;
display();
}
void display() const
{
cout << "气象局2: 当前温度:" << temperature << ", 当前湿度:" << humidity << endl;
}
~CurrentConditionsDisplay2()
{
if (weatherData)
{
delete weatherData;
weatherData = nullptr;
}
}
};
int main()
{
WeatherData* wd = new WeatherData();
CurrentConditionsDisplay* cd = new CurrentConditionsDisplay(wd);
CurrentConditionsDisplay2* cd2 = new CurrentConditionsDisplay2(wd);
// wd修改天气信息 并通知展示板
wd->setMeasurements(80, 65, 30.4f);
wd->setMeasurements(60, 35, 32.1f);
wd->removeObserver(cd);
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
wd->setMeasurements(60, 35, 31.1f);
return 0;
}
到了这里,关于【设计模式】Head First 设计模式——观察者模式 C++实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!