#include <iostream>
#include <vector>
#include <algorithm>
class Observer;
class Subject;
class Observer {
public:
virtual ~Observer() = default;
virtual void update(float temperature, float humidity, float pressure) = 0;
};
class Subject {
public:
virtual ~Subject() = default;
virtual void registerObserver(Observer* o) = 0;
virtual void removeObserver(Observer* o) = 0;
virtual void notifyObservers() = 0;
};
class WeatherData : public Subject {
private:
std::vector<Observer*> observers;
float temperature = 0.0f;
float humidity = 0.0f;
float pressure = 0.0f;
public:
void registerObserver(Observer* o) override {
observers.push_back(o);
std::cout << "[WeatherData] Registered an observer\n";
}
void removeObserver(Observer* o) override {
auto it = std::find(observers.begin(), observers.end(), o);
if (it != observers.end()) {
observers.erase(it);
std::cout << "[WeatherData] Removed an observer\n";
}
}
void notifyObservers() override {
for (auto* observer : observers) {
observer->update(temperature, humidity, pressure);
}
}
void setMeasurements(float temp, float hum, float press) {
std::cout << "\n--- Weather station update: temp=" << temp
<< "°C, humidity=" << hum << "%, pressure=" << press << "hPa ---\n";
temperature = temp;
humidity = hum;
pressure = press;
notifyObservers();
}
};
class CurrentConditionsDisplay : public Observer {
private:
float temperature = 0.0f;
float humidity = 0.0f;
public:
void update(float temp, float hum, float ) override {
temperature = temp;
humidity = hum;
display();
}
void display() const {
std::cout << "[Current Conditions] Temperature: " << temperature
<< "°C, humidity: " << humidity << "%\n";
}
};
class StatisticsDisplay : public Observer {
private:
float maxTemp = -100.0f;
float minTemp = 200.0f;
float sumTemp = 0.0f;
int count = 0;
public:
void update(float temp, float , float ) override {
sumTemp += temp;
count++;
if (temp > maxTemp) maxTemp = temp;
if (temp < minTemp) minTemp = temp;
display();
}
void display() const {
std::cout << "[Statistics] Average temperature: " << (sumTemp / count)
<< "°C, max: " << maxTemp
<< "°C, min: " << minTemp << "°C\n";
}
};
class ForecastDisplay : public Observer {
private:
float lastPressure = 0.0f;
float currentPressure = 0.0f;
public:
void update(float , float , float pressure) override {
lastPressure = currentPressure;
currentPressure = pressure;
display();
}
void display() const {
std::cout << "[Forecast] ";
if (currentPressure > lastPressure) {
std::cout << "The weather is improving!\n";
} else if (currentPressure < lastPressure) {
std::cout << "The weather may get colder, bring an umbrella!\n";
} else {
std::cout << "The weather remains basically unchanged.\n";
}
}
};
int main() {
WeatherData weatherData;
CurrentConditionsDisplay currentDisplay;
StatisticsDisplay statsDisplay;
ForecastDisplay forecastDisplay;
weatherData.registerObserver(¤tDisplay);
weatherData.registerObserver(&statsDisplay);
weatherData.registerObserver(&forecastDisplay);
weatherData.setMeasurements(25.0f, 65.0f, 1013.0f);
weatherData.setMeasurements(27.5f, 70.0f, 1012.5f);
weatherData.setMeasurements(26.0f, 68.0f, 1012.0f);
weatherData.removeObserver(&forecastDisplay);
weatherData.setMeasurements(24.0f, 60.0f, 1014.0f);
return 0;
}