Quantcast
Channel: SCN: Message List
Viewing all articles
Browse latest Browse all 8088

Observer Pattern applied in Abap

$
0
0

Observer Pattern

 

Observer pattern is a well known pattern especially with Java, here i continue my work in patterns.

This is my humble understanding of a way how we can apply observer pattern

 

 

 

The main components of this pattern is:

 

Observer pattern:

  • Subject
  • Observer
  • Context

 

 

Why do we need?

 

Cant i do without this pattern, well of course you can do although you will be having a tightly coupled application

 

The main reason is we don't want to couple the objects

 

The main goal is the " Least knowledge in objects across each other"

 

The trick here is the use of the Events in ABAP where an event gets raised and then that will be handled by a listener!!

 

Subject:

Its the main object the core data that we will be working with

You could have multiple implementations of the subject

 

One approach: is to have an interface where we can extract the event.

 

Here is a code sample: Subject is data based on the sales order item data when there is a change it will fire the event below

 

interface lif_subject.

   EVENTS: SUBJECT_IS_CHANGED.

ENDINTERFACE.

 

 

Here is the subject:

 

 

class lcl_subject definition .

 

public section.

INTERFACES lif_subject.

   methods CONSTRUCTOR

     importing

       !IV_MATNR type MATNR

       !IV_SPRAS type SPRAS

       .

    methods GET_MATNR

     returning

       value(RV_MATNR) type MATNR .

   methods GET_SPRAS

     returning

       value(RV_SPRAS) type SPRAS .

    methods SET_MATNR

     importing

       !IV_MATNR type MATNR .

   methods SET_SPRAS

     importing

       !IV_SPRAS type SPRAS .

 

protected section.

private section.

   data MV_MATNR type MATNR .

   data MV_SPRAS type SPRAS .

ENDCLASS.

 

 

CLASS lcl_subject IMPLEMENTATION.

 

METHOD constructor.

   mv_matnr = iv_matnr.

   mv_spras = iv_spras.

ENDMETHOD.

 

METHOD get_matnr.

   rv_matnr = mv_matnr.

ENDMETHOD.

 

METHOD get_spras.

   rv_spras = mv_spras.

ENDMETHOD.

 

METHOD set_matnr.

   mv_matnr = iv_matnr.

   RAISE EVENT lif_subject~SUBJECT_IS_CHANGED.

 

ENDMETHOD.

 

METHOD set_spras.

   mv_spras = iv_spras.

 

   RAISE EVENT lif_subject~SUBJECT_IS_CHANGED.

ENDMETHOD.

ENDCLASS.

 

 

 

Observer:

Observer is the one thats interested in the change of the subject

That could be any observer

 

Here is the code sample

 

****Observer

INTERFACE lif_observer.

METHODS: update.

ENDINTERFACE.

 

 

class lcl_observer1 DEFINITION.

PUBLIC SECTION.

INTERFACES lif_observer.

ENDCLASS.

 

 

class lcl_observer1 IMPLEMENTATION.

 

method lif_observer~update.

WRITE:/ ' Observer 1 is updated '.

ENDMETHOD.

 

 

ENDCLASS.

 

 

class lcl_observer2 DEFINITION.

PUBLIC SECTION.

INTERFACES lif_observer.

 

ENDCLASS.

 

 

class lcl_observer2 IMPLEMENTATION.

 

method lif_observer~update.

WRITE:/ ' Observer 2 is updated '.

 

ENDMETHOD.

 

ENDCLASS.

 

 

 

 

Context:  Its the manager of the all communication like a channel

It separates the observer from the observable.

 

 

class   lcl_channel  definition.

PUBLIC SECTION.

methods: add_observer IMPORTING io_observer type REF TO lif_observer.

methods: remove_observer IMPORTING io_observer type REF TO lif_observer.

methods: constructor.

methods: notify_observers FOR EVENT lif_subject~SUBJECT_IS_CHANGED of lcl_subject IMPORTING sender.

 

PRIVATE SECTION.

DATA: lo_list type REF TO CL_OBJECT_MAP.

class-DATA: lv_key type i.

ENDCLASS.

 

 

Notice that the event listener for the subject is the channel itself

and notify_observers method is responsible for that.

 

 

 

****Manager!!

class   lcl_channel  definition.

PUBLIC SECTION.

methods: add_observer IMPORTING io_observer type REF TO lif_observer.

methods: remove_observer IMPORTING io_observer type REF TO lif_observer.

methods: constructor.

methods: notify_observers FOR EVENT lif_subject~SUBJECT_IS_CHANGED of lcl_subject IMPORTING sender.

 

PRIVATE SECTION.

DATA: lo_list type REF TO CL_OBJECT_MAP.

class-DATA: lv_key type i.

ENDCLASS.

 

class lcl_channel IMPLEMENTATION.

method constructor.

   create OBJECT lo_list.

   lv_key  = 1.

ENDMETHOD.

method add_observer.

lo_list->PUT(

   EXPORTING

     KEY      = lv_key

     VALUE    = io_observer

).

lv_key = lv_key + 1.

ENDMETHOD.

 

 

method remove_observer.

 

ENDMETHOD.

 

 

METHOD notify_observers.

DATA: lo_map_iterator TYPE REF TO CL_OBJECT_COLLECTION_ITERATOR.

DATA: lo_observer type REF TO lif_observer.

break developer.

 

lo_map_iterator ?= lo_list->GET_VALUES_ITERATOR( ).

 

while lo_map_iterator->HAS_NEXT( ) = abap_true.

lo_observer ?= lo_map_iterator->GET_NEXT( ).

lo_observer->UPDATE( ).

ENDWHILE.

 

ENDMETHOD.





Notice the use of the Collections as well cl_object_collections object in SAP Standard




I hope you find this useful



The sample code is attached as a text file






 

ENDCLASS.


Viewing all articles
Browse latest Browse all 8088

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>