設計模式最大的作用就是在變化和穩(wěn)定中間尋找隔離點,然后分離它們,從而管理變化。將變化像小兔子一樣關到籠子里,讓它在籠子里隨便跳,而不至于跳出來把你整個房間給污染掉。
設計思想
主題對象(出版者)管理某些數(shù)據(jù),當主題內(nèi)的數(shù)據(jù)改變,就會通知觀察者(訂閱者)。
觀察者模式定義了對象之間的一對多依賴,當一個對象改變狀態(tài)時,它的所有依賴者都會收到通知并自動更新。相比讓多個對象控制同一份數(shù)據(jù),可以得到更干凈的OO設計。文章來源:http://www.zghlxwxcb.cn/news/detail-692454.html
業(yè)務場景
假定現(xiàn)在有一個氣象站類,這個氣象站類會不定時更新溫度,濕度,氣壓的最新數(shù)據(jù),要求你在這些數(shù)值變化時,立即通知一些氣象局進行展示,而他們得到的數(shù)據(jù)是一樣的,但是采用的展示手段可能是不一樣的,比如有的采用圖示,有的采用文字,有的采用語音播報等,給出設計代碼。文章來源地址http://www.zghlxwxcb.cn/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++實現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!