Reference: skysky
In this chapter, we will introduce the observer mode. The following describes the class diagram of the observer mode example:
First, the code of the test program is provided:
Report zbo_dp_002_re.
* Include file for the class and Interface
Include zbo_dp_002_cl_if.
* Declare data
Data:
* Weather data class reference object
WD type ref to weather_data,
* Define subject interface reference object
Su type ref to subject,
* Concrete observers object
* Crrent condition object
CU Type ref to current_condition_display,
* For Statistics Data Object
SD type ref to statistics_display.
Start-of-selection.
* Create weather data object.
Create object WD.
* Widening cast, make the subject interface reference
* Weather data class
Su? = WD.
* Register concrete obsever to subject interface which
* Point to weather data object
* For concrete observer current condition display
Create object Cu
Exporting WD = Su.
* For concrete observer Statistics Data
Create object SD
Exporting WD = Su.
* Change the weather data, and if the data changed, the subject
* Will inform all of its observers, including current_condition_display
* And statistics_display
Call method WD-> set_measurements
Exporting TEM = '80'
Hum = '80'
Pre = '80 '.
Call method WD-> set_measurements
Exporting TEM = '81'
Hum = '82. 4'
Pre = '80 '.
Call method WD-> set_measurements
Exporting TEM = '79'
Hum = '80'
Pre = '80 '.
The following are three interfaces:
*----------------------------------------------------------------------*
* Include zbo_dp_002_cl_if *
*----------------------------------------------------------------------*
* Interface definition.
* Interface for observer which just have one method, update ()
Interface observer.
Methods:
* When the subject's data changed, it will update observer's data
Update importing temp Type F
Hum Type F
Pre Type F.
Endinterface.
* Interface for subject which used to operating observers
Interface subject.
Methods:
* Register observer to subject
Register_observer importing O type ref to observer,
* Delete observer in subject
Remove_observer importing O type ref to observer,
* Notify Observer that the status or data changed
Notify_observer.
Endinterface.
* Interface for display data
Interface display_element.
Methods:
* When data changed in subject, the observers cocould
* Call this behavior to display data after they receive
* The changed data
Display.
Endinterface.
The following defines a specific topic:
* Define concrete subject
* In our example, we define a weather data object which
* Implement the subject Interface
Class weather_data definition.
Public section.
* Define the interface
Interfaces:
Subject.
Methods:
* The data change method
Measurement_changed,
* Setter method for setting the weather data
Set_measurements
Importing TEM type F
Hum Type F
Pre Type F.
Private section.
* The structure and internal table of observers
Data: Begin of r_observers,
Observer type ref to observer,
End of r_observers.
Data: t_observers like table of r_observers.
* Instance data definition
Data hum Type F.
Data Pre Type F.
Data TEM type F.
Endclass.
* Implement weather data
Class weather_data implementation.
* Implement Interface Method
Method subject ~ Register_observer.
* Get the import observer object
* And add it to observer's table
R_observers-observer = O.
Append r_observers to t_observers.
Endmethod.
Method subject ~ Remove_observer.
* Delete observer
Delete t_observers Where observer = O.
Endmethod.
Method subject ~ Notify_observer.
* Policy observers
Loop at t_observers into r_observers.
* Update observers 'data according to the subject changed data
Call method r_observers-observer-> Update
Exporting temp = TEM
Hum = hum
Pre = pre.
Endloop.
Endmethod.
Method measurement_changed.
* When data changed, inform observer
Call method subject ~ Notify_observer.
Endmethod.
Method set_measurements.
* Set Data of weather
Me-> TEM = TEM.
Me-> hum = hum.
Me-> pre = pre.
Call method measurement_changed.
Endmethod.
Endclass.
The following defines a specific observer: current_condition_display
* Concrete observers
* Display current weather data
Class current_condition_display definition.
Public section.
* Implement two interfaces, observer and display_element
Interfaces:
Observer,
Display_element.
Methods:
* Get the initial concrete subject object
Constructor
Importing WD type ref to subject.
Private section.
Data:
TEM type F,
Hum Type F.
* Concrete subject
Data w_data type ref to weather_data.
Endclass.
Class current_condition_display implementation.
* Update data
Method observer ~ Update.
Me-> TEM = temp.
Me-> hum = hum.
Call method display_element ~ Display.
Endmethod.
* Display data
Method display_element ~ Display.
Write:/'current conditions :'.
Write:/ME-> TEM decimals 2 exponent 0,
'F degrees .'.
Write:/ME-> hum decimals 2 exponent 0,
'% Humidity .'.
Endmethod.
Method constructor.
* Widening cast because WD's type which import is interface subject
* And the me-> w_data's type is weather_data
* And weather data is more specialized than interface subject
Me-> w_data? = WD.
* Register current condition observer to subject
Call method w_data-> subject ~ Register_observer
Exporting o = me.
Endmethod.
Endclass.
The following defines another observer: statistics_display
* Display Statistics Data
Class statistics_display definition.
Public section.
* Implement two interfaces, observer and display_element
Interfaces:
Observer,
Display_element.
Methods:
* Get the initial concrete subject object
Constructor
Importing WD type ref to subject.
Private section.
Data:
Av_temp Type F, "Average Temperature
Mx_temp Type F, "Max temperature
Mi_temp Type F. "Min Temperature
Data: WD type ref to weather_data.
Endclass.
Class statistics_display implementation.
Method constructor.
* Register observer
Me-> WD? = WD.
Call method me-> WD-> subject ~ Register_observer
Exporting o = me.
Endmethod.
Method observer ~ Update.
* Local data definition
* Table Record Number
Data: num type I.
* Local Cal data
Data:
Tav_temp Type F,
Tmx_temp Type F,
Tmi_temp Type F.
* Store all the temperature which setted
Data:
Begin of r_result,
Temp Type F,
End of r_result.
Data: t_result like table of r_result.
* Get the temperature and add it to table
R_result-temp = temp.
Append r_result to t_result.
Describe table t_result lines num.
If num <> 0.
Sort t_result ascending.
* Get min temp
Read Table t_result Index 1 into r_result.
Tmi_temp = r_result-temp.
* Get Max temp
Read Table t_result index num into r_result.
Tmx_temp = r_result-temp.
* Get AVG temp
Loop at t_result into r_result.
Tav_temp = tav_temp + r_result-temp.
Endloop.
Tav_temp = tav_temp/num.
* Update instance variants
Mi_temp = tmi_temp.
Mx_temp = tmx_temp.
Av_temp = tav_temp.
Endif.
* Display result
Call method display_element ~ Display.
Endmethod.
Method display_element ~ Display.
Skip.
Write:/'statistics display :'.
Write:/'average temp: ', av_temp decimals 2 exponent 0.
Write:/'max temp: ', mx_temp decimals 2 exponent 0.
Write:/'min temp: ', mi_temp decimals 2 exponent 0.
Endmethod.
Endclass.