notifyObservers second variant

This commit is contained in:
Alexander Zhirov 2022-11-11 10:56:59 +03:00
parent 850cb17d02
commit b6e1ec089c
9 changed files with 115 additions and 8 deletions

View File

@ -1,3 +1,12 @@
# Наблюдатель # Наблюдатель
Наблюдатель — это поведенческий паттерн проектирования, который создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах. Наблюдатель — это поведенческий паттерн проектирования, который создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах.
При использовании паттерна возможен как запрос, так и активная доставка данных от субъекта (запрос считается более "правильным").
- **Активная доставка** - передача субъектом аргументов в качестве параметров функции `update()`
- **Запрос** - подразумевает получение необходимых параметров от субъекта внутри функции `update()`
## Принципы
- Стремиться к слабой связанности взаимодействующих объектов

View File

@ -1,17 +1,22 @@
module observer.app; module observer.app;
import observer.weatherdata; import observer.weatherdata;
import observer.currentconditionsdisplay; import observer.currentconditionsdisplay;
import observer.heatindexdisplay; import observer.heatindexdisplay;
import observer.forecastdisplay;
import observer.statiscticdisplay;
void main() void main()
{ {
WeatherData weatherData = new WeatherData(); WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData); HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(82, 70, 29.2f);
weatherData.removeObserver(heatIndexDisplay); weatherData.removeObserver(forecastDisplay);
weatherData.setMeasurements(78, 90, 29.2f); weatherData.setMeasurements(78, 90, 29.2f);
weatherData.setMeasurements(81, 72, 29.5f); weatherData.setMeasurements(81, 72, 29.5f);
} }

View File

@ -1,4 +1,5 @@
module observer.currentconditionsdisplay; module observer.currentconditionsdisplay;
import observer.displayelement; import observer.displayelement;
import observer.observer; import observer.observer;
import observer.weatherdata; import observer.weatherdata;
@ -14,13 +15,14 @@ private:
public: public:
this(WeatherData weatherData) this(WeatherData weatherData)
{ {
this.weatherData = weatherData;
weatherData.registerObserver(this); weatherData.registerObserver(this);
} }
override void update(float temperature, float humidity, float pressure) override void update()
{ {
this.temperature = temperature; this.temperature = weatherData.getTemperature;
this.humidity = humidity; this.humidity = weatherData.getHumidity;
display(); display();
} }

View File

@ -0,0 +1,40 @@
module observer.forecastdisplay;
import observer.displayelement;
import observer.observer;
import observer.weatherdata;
import std.stdio : write, writeln;
import std.format : format;
class ForecastDisplay : Observer, DisplayElement
{
private:
float currentPressure = 29.92f;
float lastPressure;
WeatherData weatherData;
public:
this(WeatherData weatherData)
{
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
override void update()
{
lastPressure = currentPressure;
currentPressure = weatherData.getPressure;
display();
}
override void display()
{
write("Forecast: ");
if (currentPressure > lastPressure) {
writeln("Improving weather on the way!");
} else if (currentPressure == lastPressure) {
writeln("More of the same");
} else if (currentPressure < lastPressure) {
writeln("Watch out for cooler, rainy weather");
}
}
}

View File

@ -1,4 +1,5 @@
module observer.heatindexdisplay; module observer.heatindexdisplay;
import observer.displayelement; import observer.displayelement;
import observer.observer; import observer.observer;
import observer.weatherdata; import observer.weatherdata;
@ -22,12 +23,13 @@ private:
public: public:
this(WeatherData weatherData) this(WeatherData weatherData)
{ {
this.weatherData = weatherData;
weatherData.registerObserver(this); weatherData.registerObserver(this);
} }
override void update(float temperature, float humidity, float pressure) override void update()
{ {
this.heatIndex = computeHeatIndex(temperature, humidity); this.heatIndex = computeHeatIndex(weatherData.getTemperature, weatherData.getHumidity);
display(); display();
} }

View File

@ -2,5 +2,5 @@ module observer.observer;
interface Observer interface Observer
{ {
void update(float temp, float humidity, float pressure); void update();
} }

View File

@ -0,0 +1,47 @@
module observer.statiscticdisplay;
import observer.displayelement;
import observer.observer;
import observer.weatherdata;
import std.stdio : writeln;
import std.format : format;
class StatisticsDisplay : Observer, DisplayElement
{
private:
float maxTemp = 0.0f;
float minTemp = 200;
float tempSum= 0.0f;
int numReadings;
WeatherData weatherData;
public:
this(WeatherData weatherData)
{
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
override void update()
{
tempSum += weatherData.getTemperature;
numReadings++;
if (weatherData.getTemperature > maxTemp)
{
maxTemp = weatherData.getTemperature;
}
if (weatherData.getTemperature < minTemp)
{
minTemp = weatherData.getTemperature;
}
display();
}
override void display()
{
writeln("Avg/Max/Min temperature = ", (tempSum / numReadings), '/', maxTemp, '/', minTemp);
// writeln("Avg/Max/Min temperature = ".format(temperature), "F degrees and %3.1f%% humidity".format(humidity));
}
}

View File

@ -1,4 +1,5 @@
module observer.subject; module observer.subject;
import observer.observer; import observer.observer;
interface Subject interface Subject

View File

@ -1,4 +1,5 @@
module observer.weatherdata; module observer.weatherdata;
import observer.subject; import observer.subject;
import observer.observer; import observer.observer;
import std.algorithm : remove, countUntil; import std.algorithm : remove, countUntil;
@ -25,7 +26,7 @@ public:
{ {
foreach (Observer o; observers) foreach (Observer o; observers)
{ {
o.update(temperature, humidity, pressure); o.update();
} }
} }