diff --git a/observer/README.md b/observer/README.md index caaaf5d..29c8b86 100644 --- a/observer/README.md +++ b/observer/README.md @@ -1,3 +1,12 @@ # Наблюдатель Наблюдатель — это поведенческий паттерн проектирования, который создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах. + +При использовании паттерна возможен как запрос, так и активная доставка данных от субъекта (запрос считается более "правильным"). + +- **Активная доставка** - передача субъектом аргументов в качестве параметров функции `update()` +- **Запрос** - подразумевает получение необходимых параметров от субъекта внутри функции `update()` + +## Принципы + +- Стремиться к слабой связанности взаимодействующих объектов diff --git a/observer/app.d b/observer/app.d index 9b44bc3..3db78f5 100644 --- a/observer/app.d +++ b/observer/app.d @@ -1,17 +1,22 @@ module observer.app; + import observer.weatherdata; import observer.currentconditionsdisplay; import observer.heatindexdisplay; +import observer.forecastdisplay; +import observer.statiscticdisplay; void main() { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData); + ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); + StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); - weatherData.removeObserver(heatIndexDisplay); + weatherData.removeObserver(forecastDisplay); weatherData.setMeasurements(78, 90, 29.2f); weatherData.setMeasurements(81, 72, 29.5f); } diff --git a/observer/currentconditionsdisplay.d b/observer/currentconditionsdisplay.d index 815d082..aaec318 100644 --- a/observer/currentconditionsdisplay.d +++ b/observer/currentconditionsdisplay.d @@ -1,4 +1,5 @@ module observer.currentconditionsdisplay; + import observer.displayelement; import observer.observer; import observer.weatherdata; @@ -14,13 +15,14 @@ private: public: this(WeatherData weatherData) { + this.weatherData = weatherData; weatherData.registerObserver(this); } - override void update(float temperature, float humidity, float pressure) + override void update() { - this.temperature = temperature; - this.humidity = humidity; + this.temperature = weatherData.getTemperature; + this.humidity = weatherData.getHumidity; display(); } diff --git a/observer/forecastdisplay.d b/observer/forecastdisplay.d new file mode 100644 index 0000000..9840471 --- /dev/null +++ b/observer/forecastdisplay.d @@ -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"); + } + } +} diff --git a/observer/heatindexdisplay.d b/observer/heatindexdisplay.d index eedc621..ac98ee8 100644 --- a/observer/heatindexdisplay.d +++ b/observer/heatindexdisplay.d @@ -1,4 +1,5 @@ module observer.heatindexdisplay; + import observer.displayelement; import observer.observer; import observer.weatherdata; @@ -22,12 +23,13 @@ private: public: this(WeatherData weatherData) { + this.weatherData = weatherData; 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(); } diff --git a/observer/observer.d b/observer/observer.d index a4e5e08..8665f4d 100644 --- a/observer/observer.d +++ b/observer/observer.d @@ -2,5 +2,5 @@ module observer.observer; interface Observer { - void update(float temp, float humidity, float pressure); + void update(); } diff --git a/observer/statiscticdisplay.d b/observer/statiscticdisplay.d new file mode 100644 index 0000000..55e7601 --- /dev/null +++ b/observer/statiscticdisplay.d @@ -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)); + } +} diff --git a/observer/subject.d b/observer/subject.d index 668feb0..8fa85b1 100644 --- a/observer/subject.d +++ b/observer/subject.d @@ -1,4 +1,5 @@ module observer.subject; + import observer.observer; interface Subject diff --git a/observer/weatherdata.d b/observer/weatherdata.d index 4029c45..9970d1b 100644 --- a/observer/weatherdata.d +++ b/observer/weatherdata.d @@ -1,4 +1,5 @@ module observer.weatherdata; + import observer.subject; import observer.observer; import std.algorithm : remove, countUntil; @@ -25,7 +26,7 @@ public: { foreach (Observer o; observers) { - o.update(temperature, humidity, pressure); + o.update(); } }