This repository has been archived on 2022-11-09 . You can view files and clone it, but cannot push or open issues or pull requests.
11 changed files with
366 additions and
0 deletions
@ -0,0 +1,6 @@
Паттерн "Наблюдатель" определяет отношение "один-ко-многим" между объектами таким образом, что при изменении состояния одного объекта происходит автоматическое оповещение и обновление всех зависимых объектов.
При использовании паттерна возможен как запрос, так и активная доставка данных от субъекта (запрос считается более "правильным").
*Принцип:*
- Слабосвязанные структуры более гибки и лучше выдерживают изменения.
@ -0,0 +1,38 @@
/*
* 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 ;
}
} ;
@ -0,0 +1,16 @@
/*
* DisplayElement . hpp
*
* Created on : 31 о к т . 2021 г .
* Author : alexander
*/
# pragma once
class DisplayElement
{
public :
virtual void display ( ) const = 0 ;
virtual ~ DisplayElement ( ) { }
} ;
@ -0,0 +1,47 @@
/*
* 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 ;
}
} ;
@ -0,0 +1,46 @@
/*
* 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 ;
}
} ;
@ -0,0 +1,16 @@
/*
* 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 ( ) { }
} ;
@ -0,0 +1,48 @@
/*
* 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 ;
}
} ;
@ -0,0 +1,20 @@
/*
* 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 ( ) { }
} ;
@ -0,0 +1,72 @@
/*
* 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 ;
}
} ;
@ -0,0 +1,28 @@
/*
* 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 ;
}
@ -0,0 +1,29 @@
// 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:
};