技术开发 频道

ABAP与设计模式之观察者模式

【IT168 技术文章】

    这章我们介绍观察者模式,下面先给出观察者模式的例子的类图:


    首先给出测试程序的代码:
    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.
0
相关文章