Definition:
The observer mode defines one-to-multiple dependencies between objects. In this way, when an object changes its state, all its dependent persons will receive notifications and update them automatically.
Scenario:
We have a weather station. We use weatherdata to obtain the latest data from the weather station and update the data on the bulletin board. We have defined two bulletin boards, one being a thermometer that displays the latest temperature, and the other being the latest data showing all the current temperature, humidity, and pressure.
Class diagram:
The C ++ code is as follows:
# Include <iostream>
# Include <list>
# Include <string>
# Include <algorithm>
Using namespace STD;
Class observer;
// Subject
Class subject
{
Public:
Virtual void registerobserver (Observer * o) = 0;
Virtual void removeobserver (Observer * o) = 0;
Virtual void policyobserver () = 0;
Float gettemperature ();
Float gethumidity ();
Float getpressure ();
Protected:
Float m_temperature;
Float m_humidity;
Float m_pressure;
};
// Observer
Class observer
{
Public:
Observer (subject * pweaterdata );
Virtual ~ Observer (){};
Virtual void Update () = 0;
Subject * getweaterdata ();
Protected:
Subject * m_weaterdata;
};
Class displayelement
{
Public:
Virtual void display () = 0;
};
Class weatherdata: public subject
{
Public:
Weatherdata ();
~ Weatherdata ();
Void registerobserver (Observer * O );
Void removeobserver (Observer * O );
Void notifyobserver ();
Void measurementschanged ();
Void setmeasurements (float temperature, float humidity, float pressure );
PRIVATE:
List <Observer *> m_lobserver;
};
// Display the current condition
Class currentconditionsdisplay: public observer, public displayelement
{
Public:
Currentconditionsdisplay (subject * pweaterdata );
~ Currentconditionsdisplay ();
Void Update ();
Void display ();
PRIVATE:
Float m_template; // Temperature
Float m_humidity; // humidity
Float m_pressure; // pressure
};
// Thermometer
Class thermometer: public observer, public displayelement
{
Public:
Thermometer (subject * pweaterdata );
~ Thermometer ();
Void Update ();
Void display ();
PRIVATE:
Float m_template; // Temperature
};
Float subject: gettemperature ()
{
Return m_temperature;
}
Float subject: gethumidity ()
{
Return m_humidity;
}
Float subject: getpressure ()
{
Return m_pressure;
}
Observer: Observer (subject * pweaterdata)
{
M_weaterdata = pweaterdata;
}
Subject * Observer: getweaterdata ()
{
Return m_weaterdata;
}
Weatherdata: weatherdata ()
{
M_temperature = 0;
M_humidity = 0;
M_pressure = 0;
}
Weatherdata ::~ Weatherdata ()
{
List <Observer *>: iterator ITER, temp;
For (iter = m_lobserver.begin (); iter! = M_lobserver.end (); ++ ITER)
{
Delete (* ITER );
}
M_lobserver.clear ();
}
Void weatherdata: registerobserver (Observer * O)
{
M_lobserver.push_back (O );
}
Void weatherdata: removeobserver (Observer * O)
{
List <Observer *>: iterator ITER;
Iter = STD: Find (m_lobserver.begin (), m_lobserver.end (), O );
If (m_lobserver.end ()! = ITER)
{
M_lobserver.erase (ITER );
}
}
Void weatherdata: notifyobserver ()
{
List <Observer *>: iterator ITER;
For (iter = m_lobserver.begin (); iter! = M_lobserver.end (); ++ ITER)
{
(* ITER)-> Update ();
}
}
Void weatherdata: measurementschanged ()
{
Notifyobserver ();
}
Void weatherdata: setmeasurements (float temperature, float humidity, Float Pressure)
{
M_temperature = temperature;
M_humidity = humidity;
M_pressure = pressure;
Measurementschanged ();
}
Currentconditionsdisplay: currentconditionsdisplay (subject * pweaterdata): Observer (pweaterdata)
{
Pweaterdata-> registerobserver (this );
}
Currentconditionsdisplay ::~ Currentconditionsdisplay ()
{
M_weaterdata = NULL;
}
Void currentconditionsdisplay: Update ()
{
M_template = m_weaterdata-> gettemperature ();
M_humidity = m_weaterdata-> gethumidity ();
M_pressure = m_weaterdata-> getpressure ();
Display ();
}
Void currentconditionsdisplay: Display ()
{
Printf ("current conditions % f0.2f degrees and % 0.2f % s humidity and pressure % 0.2f \ n", m_template, m_humidity, "%", m_pressure );
}
Thermometer: Thermometer (subject * pweaterdata): Observer (pweaterdata)
{
Pweaterdata-> registerobserver (this );
}
Thermometer ::~ Thermometer ()
{
M_weaterdata = NULL;
}
Void thermometer: Update ()
{
M_template = m_weaterdata-> gettemperature ();
Display ();
}
Void thermometer: Display ()
{
Printf ("current conditions % f0.2f degrees \ n", m_template );
}
Int main ()
{
Weatherdata * pweatherdata = new weatherdata ();
Currentconditionsdisplay * pcurrentconditionsdisplay = new currentconditionsdisplay (pweatherdata );
Thermometer * pthermometer = new Thermometer (pweatherdata );
Pweatherdata-> setmeasurements (123,456,789 );
// When the observer is removed, the memory needs to be manually released
Pcurrentconditionsdisplay-> getweaterdata ()-> removeobserver (pcurrentconditionsdisplay );
Pweatherdata-> setmeasurements (789,456,123 );
// After re-registration, the memory is managed by the topic
Pcurrentconditionsdisplay-> getweaterdata ()-> registerobserver (pcurrentconditionsdisplay );
Pweatherdata-> setmeasurements (135,257,479 );
Delete pweatherdata;
Return 0;
}
The result is as follows:
Current conditions 123.000f degrees and 456.00% humidity and pressure 789.00
Current conditions 123.00f degrees
Current conditions 789.00f degrees
Current conditions 135.00f degrees
Current conditions 135.00f degrees and 257.00% humidity and pressure 479.00
Reference: head first design model