版权声明:本文为博主原创文章,如有需要,可以转载,但请注明出处。 https://blog.csdn.net/xunye_dream/article/details/84718963
对于程序员来说,最好的交流应该是代码了。直接上代码吧,如有更好的实现方式,或代码有不妥的地方,也请大神赐教吧。
一、目录结构
二、接口部分代码
1、主题——Subject.h
#ifndef INC_INTERFACE_SUBJECT_H_
#define INC_INTERFACE_SUBJECT_H_
struct Observer;
struct Subject
{
virtual ~Subject() {};
virtual void registerObserver(const Observer* o) = 0;
virtual void removeObserver(const Observer* o) = 0;
virtual void notifyObservers() = 0;
};
#endif
2、订阅者——Observer.h
#ifndef INC_INTERFACE_OBSERVER_H_
#define INC_INTERFACE_OBSERVER_H_
struct Observer
{
virtual ~Observer() {}
virtual void update(float temp, float humidity, float pressure) = 0;
};
#endif
3、显示——DisplayElement.h
#ifndef INC_INTERFACE_DISPLAYELEMENT_H_
#define INC_INTERFACE_DISPLAYELEMENT_H_
struct DisplayElement
{
virtual ~DisplayElement() {}
virtual void display() = 0;
};
#endif
三、实现部分
1、发布者——WeatherData.h
#ifndef INC_PUBLISHER_WEATHERDATA_H_
#define INC_PUBLISHER_WEATHERDATA_H_
#include "interface/Observer.h"
#include "interface/Subject.h"
#include <vector>
#include <algorithm>
using std::vector;
struct WeatherData : Subject
{
WeatherData() : temperature(0), humidity(0), pressure(0)
{
observers.clear();
}
void registerObserver(const Observer* o) override
{
observers.push_back(o);
}
void removeObserver(const Observer* o) override
{
auto it = std::find(observers.begin(), observers.end(), o);
if (it != observers.end())
{
observers.erase(it);
}
}
void setMeasurements(float temperature, float humidity, float pressure)
{
this->temperature = temperature;
this->humidity = humidity;
this->pressure = pressure;
measurementsChanged();
}
private:
void notifyObservers() override
{
for (auto observer : observers)
{
const_cast<Observer*>(observer)->update(temperature, humidity, pressure);
}
}
void measurementsChanged()
{
notifyObservers();
}
private:
float temperature;
float humidity;
float pressure;
vector<const Observer*> observers;
};
#endif
2、订阅者——CurrentConditionsDisplay.h
#ifndef INC_SUBSCRIBER_CURRENTCONDITIONSDISPLAY_H_
#define INC_SUBSCRIBER_CURRENTCONDITIONSDISPLAY_H_
#include "interface/Observer.h"
#include "interface/DisplayElement.h"
#include "interface/Subject.h"
#include <iostream>
struct CurrentConditionsDisplay : Observer
, private DisplayElement
{
CurrentConditionsDisplay(Subject& weatherData) : temperature(0), humidity(0)
, weatherData(weatherData)
{
this->weatherData.registerObserver(this);
}
void update(float temperature, float humidity, float pressure) override
{
this->temperature = temperature;
this->humidity = humidity;
display();
}
private:
void display() override
{
std::cout << "Current conditions: "
<< temperature << "F degrees and "
<< humidity << "% humidity" << std::endl;
}
private:
float temperature;
float humidity;
Subject& weatherData;
};
#endif
四、使用
1、main.cpp
#include <iostream>
#include "publisher/WeatherData.h"
#include "subscriber/CurrentConditionsDisplay.h"
using namespace std;
int main(int argc, char **argv)
{
WeatherData weatherData;
CurrentConditionsDisplay currentDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(99, 45, 23.4f);
weatherData.removeObserver(¤tDisplay);
weatherData.setMeasurements(99, 45, 23.4f);
return 0;
}
2、显示
五、总结
从上述的接口实现部分可以看出,观察者模式的实现符合面向接口编程的原则。
发布者和订阅者是1对多的关系。
接口类的实现,记得添加虚析构函数。