这章我们介绍观察者模式,下面先给出观察者模式的例子的类图:
image首先给出测试程序的代码:
REPORT ZBOBO_DP_002_RE .
*Include file for the class and interface
include zbobo_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 to
* 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'.
下面是三个interface:
*----------------------------------------------------------------------*
* INCLUDE ZBOBO_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 could
* call this behavior to display data after they receive
* the changed data
display.
endinterface.
下面定义一个具体的主题:
*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.
* Notify 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.
下面定义一个具体的观察者: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.
下面定义另外一个观察者: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.
网友评论