观察者模式
Published: 2020-11-19
使用场景 #
目标对象的接口 #
class Subject {
public:
virtual ~Subject() {}
virtual void registerObserver(Observer *o) = 0;
virtual void removeObserver(Observer *o) = 0;
virtual void notifyObservers() = 0;
};
具体的目标对象 #
class WeatherData : public Subject {
public:
WeatherData();
virtual ~WeatherData();
virtual void registerObserver(Observer *o);
virtual void removeObserver(Observer *o);
virtual void notifyObservers();
void measurementsChanged();
void setMeasurements(float temperature, float humidity, float pressure);
float temperature();
float humidity();
float pressure();
private:
std::vector<Observer*> *observers_;
float temperature_;
float humidity_;
float pressure_;
};
void WeatherData::notifyObservers() {
int i;
for (i = 0; i < observers_->size(); ++i) {
Observer* observer = (*observers_)[i];
observer->update(temperature_, humidity_, pressure_);
}
}
void WeatherData::measurementsChanged() {
notifyObservers();
}
void WeatherData::setMeasurements(float temperature, float humidity,
float pressure) {
temperature_ = temperature;
humidity_ = humidity;
pressure_ = pressure;
measurementsChanged();
}
观察者更新接口 #
class Observer {
public:
virtual ~Observer() {}
virtual void update(float temp, float humdity, float pressure) = 0;
};
观察者显示接口 #
class DisplayElement {
public:
virtual ~DisplayElement() {}
virtual void display() = 0;
};
具体的观察者 #
class StatisticsDisplay : public Observer, public DisplayElement {
public:
explicit StatisticsDisplay(Subject *weather_data);
~StatisticsDisplay();
virtual void update(float temp, float humidity, float pressure);
virtual void display();
private:
float max_temp_;
float min_temp_;
float temp_sum_;
int num_readings_;
Subject *weather_data_;
DISALLOW_COPY_AND_ASSIGN(StatisticsDisplay);
};
StatisticsDisplay::StatisticsDisplay(Subject *weather_data)
: weather_data_(weather_data), max_temp_(0.0f), min_temp_(200),
temp_sum_(0.0f), num_readings_(0) {
weather_data_->registerObserver(this);
}
void StatisticsDisplay::update(float temp, float humidity, float pressure) {
temp_sum_ += temp;
num_readings_++;
if (temp > max_temp_) {
max_temp_ = temp;
}
if (temp < min_temp_) {
min_temp_ = temp;
}
display();
}
void StatisticsDisplay::display() {
printf("Avg/Max/Min temperature = %f/%f/%f\n", (temp_sum_ / num_readings_),
max_temp_, min_temp_);
}
测试 #
int main(int argc, char *argv[]) {
WeatherData *weather_data = new WeatherData();
CurrentConditionsDisplay *current_display =
new CurrentConditionsDisplay(weather_data);
StatisticsDisplay *statistics_display =
new StatisticsDisplay(weather_data);
ForecastDisplay *forecast_display =
new ForecastDisplay(weather_data);
weather_data->setMeasurements(80, 65, 30.4f);
weather_data->setMeasurements(82, 70, 29.2f);
weather_data->setMeasurements(78, 90, 29.2f);
}
Next: 有趣的人
Previous: 单例模式