Compare commits
No commits in common. "lesson_2" and "master" have entirely different histories.
|
@ -1,6 +0,0 @@
|
||||||
Паттерн "Наблюдатель" определяет отношение "один-ко-многим" между объектами таким образом, что при изменении состояния одного объекта происходит автоматическое оповещение и обновление всех зависимых объектов.
|
|
||||||
|
|
||||||
При использовании паттерна возможен как запрос, так и активная доставка данных от субъекта (запрос считается более "правильным").
|
|
||||||
|
|
||||||
*Принцип:*
|
|
||||||
- Слабосвязанные структуры более гибки и лучше выдерживают изменения.
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* CurrentConditionsDisplay.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Observer.hpp"
|
|
||||||
#include "DisplayElement.hpp"
|
|
||||||
#include "WeatherData.hpp"
|
|
||||||
|
|
||||||
class CurrentConditionsDisplay: public Observer, public DisplayElement
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
float temperature;
|
|
||||||
float humidity;
|
|
||||||
WeatherData &weatherData;
|
|
||||||
public:
|
|
||||||
CurrentConditionsDisplay(WeatherData &weatherData) :
|
|
||||||
temperature(0.0), humidity(0.0), weatherData(weatherData)
|
|
||||||
{
|
|
||||||
weatherData.registerObserver(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float temperature, float humidity, float pressure) override
|
|
||||||
{
|
|
||||||
this->temperature = temperature;
|
|
||||||
this->humidity = humidity;
|
|
||||||
display();
|
|
||||||
}
|
|
||||||
|
|
||||||
void display() const override
|
|
||||||
{
|
|
||||||
std::cout << "Current conditions: " << temperature << "F degrees and " << humidity << "% humidity" << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* DisplayElement.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class DisplayElement
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void display() const = 0;
|
|
||||||
|
|
||||||
virtual ~DisplayElement() {}
|
|
||||||
};
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* ForecastDisplay.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Observer.hpp"
|
|
||||||
#include "DisplayElement.hpp"
|
|
||||||
#include "WeatherData.hpp"
|
|
||||||
|
|
||||||
class ForecastDisplay: public Observer, public DisplayElement
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
float currentPressure;
|
|
||||||
float lastPressure;
|
|
||||||
WeatherData &weatherData;
|
|
||||||
public:
|
|
||||||
ForecastDisplay(WeatherData &weatherData) :
|
|
||||||
currentPressure(29.92), lastPressure(0.0), weatherData(weatherData)
|
|
||||||
{
|
|
||||||
weatherData.registerObserver(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float temperature, float humidity, float pressure) override
|
|
||||||
{
|
|
||||||
this->lastPressure = this->currentPressure;
|
|
||||||
this->currentPressure = pressure;
|
|
||||||
|
|
||||||
display();
|
|
||||||
}
|
|
||||||
|
|
||||||
void display() const override
|
|
||||||
{
|
|
||||||
std::cout << "Forecast: ";
|
|
||||||
if (currentPressure > lastPressure) {
|
|
||||||
std::cout << "Improving weather on the way!";
|
|
||||||
} else if (currentPressure == lastPressure) {
|
|
||||||
std::cout << "More of the same";
|
|
||||||
} else if (currentPressure < lastPressure) {
|
|
||||||
std::cout << "Watch out for cooler, rainy weather";
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* HeatIndexDisplay.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Observer.hpp"
|
|
||||||
#include "DisplayElement.hpp"
|
|
||||||
#include "WeatherData.hpp"
|
|
||||||
|
|
||||||
class HeatIndexDisplay: public Observer, public DisplayElement
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
float heatIndex;
|
|
||||||
WeatherData &weatherData;
|
|
||||||
|
|
||||||
float computeHeatIndex(float t, float rh)
|
|
||||||
{
|
|
||||||
float index = (float) ((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh) + (0.00941695 * (t * t)) + (0.00728898 * (rh * rh))
|
|
||||||
+ (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) + (0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t))
|
|
||||||
+ (0.0000291583 * (rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) + (0.000000197483 * (t * rh * rh * rh))
|
|
||||||
- (0.0000000218429 * (t * t * t * rh * rh)) + 0.000000000843296 * (t * t * rh * rh * rh))
|
|
||||||
- (0.0000000000481975 * (t * t * t * rh * rh * rh)));
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
HeatIndexDisplay(WeatherData &weatherData) : heatIndex(0.0), weatherData(weatherData)
|
|
||||||
{
|
|
||||||
weatherData.registerObserver(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float temperature, float humidity, float pressure) override
|
|
||||||
{
|
|
||||||
heatIndex = computeHeatIndex(temperature, humidity);
|
|
||||||
|
|
||||||
display();
|
|
||||||
}
|
|
||||||
|
|
||||||
void display() const override
|
|
||||||
{
|
|
||||||
std::cout << "Heat index is " << heatIndex << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
/*
|
|
||||||
* Observer.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class Observer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void update(float temp, float humidity, float pressure) = 0;
|
|
||||||
|
|
||||||
virtual ~Observer() {}
|
|
||||||
};
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* StaticDisplay.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Observer.hpp"
|
|
||||||
#include "DisplayElement.hpp"
|
|
||||||
#include "WeatherData.hpp"
|
|
||||||
|
|
||||||
class StaticDisplay: public Observer, public DisplayElement
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
float maxTemp;
|
|
||||||
float minTemp;
|
|
||||||
float tempSum;
|
|
||||||
int numReadings;
|
|
||||||
WeatherData &weatherData;
|
|
||||||
public:
|
|
||||||
StaticDisplay(WeatherData &weatherData) :
|
|
||||||
maxTemp(0.0), minTemp(200.0), tempSum(0.0), numReadings(0), weatherData(weatherData)
|
|
||||||
{
|
|
||||||
weatherData.registerObserver(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float temperature, float humidity, float pressure) override
|
|
||||||
{
|
|
||||||
this->tempSum += temperature;
|
|
||||||
this->numReadings++;
|
|
||||||
|
|
||||||
if (temperature > this->maxTemp) {
|
|
||||||
this->maxTemp = temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temperature < this->minTemp) {
|
|
||||||
this->minTemp = temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
display();
|
|
||||||
}
|
|
||||||
|
|
||||||
void display() const override
|
|
||||||
{
|
|
||||||
std::cout << "Avg/Max/Min temperature = " << (tempSum / numReadings)
|
|
||||||
<< "/" << maxTemp << "/" << minTemp << std::endl;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* Subject.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Observer.hpp"
|
|
||||||
|
|
||||||
class Subject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void registerObserver(Observer &o) = 0;
|
|
||||||
virtual void removeObserver(Observer &o) = 0;
|
|
||||||
virtual void notifyObservers() = 0;
|
|
||||||
|
|
||||||
virtual ~Subject() {}
|
|
||||||
};
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* WeatherData.hpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Subject.hpp"
|
|
||||||
#include <list>
|
|
||||||
#include <functional>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
class WeatherData: public Subject
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::list<std::reference_wrapper<Observer>> observers;
|
|
||||||
float temperature;
|
|
||||||
float humidity;
|
|
||||||
float pressure;
|
|
||||||
public:
|
|
||||||
void registerObserver(Observer &o) override
|
|
||||||
{
|
|
||||||
observers.push_back(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeObserver(Observer &o) override
|
|
||||||
{
|
|
||||||
observers.erase(std::find_if(observers.cbegin(), observers.cend(), [&](const std::reference_wrapper<Observer> &item)
|
|
||||||
{
|
|
||||||
return &item.get() == &o;
|
|
||||||
}));
|
|
||||||
std::cout << "Осталось в листе: " << observers.size() << " элементов" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void notifyObservers() override
|
|
||||||
{
|
|
||||||
for (Observer &observer : observers)
|
|
||||||
{
|
|
||||||
observer.update(temperature, humidity, pressure);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void measurementsChanged()
|
|
||||||
{
|
|
||||||
notifyObservers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMeasurements(float temperature, float humidity, float pressure)
|
|
||||||
{
|
|
||||||
this->temperature = temperature;
|
|
||||||
this->humidity = humidity;
|
|
||||||
this->pressure = pressure;
|
|
||||||
measurementsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
float getTemperature()
|
|
||||||
{
|
|
||||||
return temperature;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getHumidity()
|
|
||||||
{
|
|
||||||
return humidity;
|
|
||||||
}
|
|
||||||
|
|
||||||
float getPressure()
|
|
||||||
{
|
|
||||||
return pressure;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,28 +0,0 @@
|
||||||
/*
|
|
||||||
* main.cpp
|
|
||||||
*
|
|
||||||
* Created on: 31 окт. 2021 г.
|
|
||||||
* Author: alexander
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "WeatherData.hpp"
|
|
||||||
#include "CurrentConditionsDisplay.hpp"
|
|
||||||
#include "StaticDisplay.hpp"
|
|
||||||
#include "ForecastDisplay.hpp"
|
|
||||||
#include "HeatIndexDisplay.hpp"
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
WeatherData weatherData;
|
|
||||||
CurrentConditionsDisplay currentDisplay(weatherData);
|
|
||||||
StaticDisplay staticDisplay(weatherData);
|
|
||||||
ForecastDisplay forecastDisplay(weatherData);
|
|
||||||
HeatIndexDisplay heatIndexDisplay(weatherData);
|
|
||||||
|
|
||||||
weatherData.setMeasurements(80, 65, 30.4f);
|
|
||||||
weatherData.setMeasurements(82, 70, 29.2f);
|
|
||||||
weatherData.setMeasurements(78, 90, 29.2f);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
// interface
|
|
||||||
|
|
||||||
class Subject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void registerObserver() = 0;
|
|
||||||
virtual void removeObserver() = 0;
|
|
||||||
virtual void notifyObserver() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Observer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void update() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// classes
|
|
||||||
|
|
||||||
class ConcreteSubject : public Subject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void getState();
|
|
||||||
void setState();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConcreteObserver : public Observer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
};
|
|
Reference in New Issue