23/11/2010

Dynamic Read Table With Key and Value

Introduction

The concepts of dynamic programming are part of the unique features that ABAP offers for business programming.

Exploiting the features of dynamic programming allows you to write powerful and flexible applications.


REPORT ZADN_SAMPLE.

*----------------------------------------------------------------------*
* -> CLASS lc_abnsample DEFINITION
*----------------------------------------------------------------------*
CLASS lc_abnsample DEFINITION.

PUBLIC SECTION.

TYPES : BEGIN OF ty_table_line,
id TYPE char02,
name TYPE char20,
phone TYPE char15,
END OF ty_table_line.

METHODS : constructor.

METHODS : get_item_by_key IMPORTING p_key TYPE char12
p_value TYPE any
EXPORTING p_item TYPE any.

PRIVATE SECTION.

TYPES : ty_table TYPE STANDARD TABLE OF ty_table_line.

DATA : it_table TYPE ty_table,
st_table TYPE LINE OF ty_table.

METHODS : load_table_data.

ENDCLASS. "lc_abnsample DEFINITION

*----------------------------------------------------------------------*
* -> CLASS lc_abnsample DEFINITION
*----------------------------------------------------------------------*
CLASS lc_abnsample IMPLEMENTATION.

METHOD constructor.

me->load_table_data( ).

ENDMETHOD. "constructor

METHOD load_table_data.

CLEAR : me->st_table.

me->st_table-id = 'AA'.
me->st_table-name = 'NAME AA'.
me->st_table-phone = 'PHONE AA'.

APPEND me->st_table TO me->it_table.

CLEAR : me->st_table.

me->st_table-id = 'BB'.
me->st_table-name = 'NAME BB'.
me->st_table-phone = 'PHONE BB'.

APPEND me->st_table TO me->it_table.

CLEAR : me->st_table.

me->st_table-id = 'CC'.
me->st_table-name = 'NAME CC'.
me->st_table-phone = 'PHONE CC'.

APPEND me->st_table TO me->it_table.

CLEAR : me->st_table.

ENDMETHOD. "load_table_data

METHOD get_item_by_key.

READ TABLE me->it_table WITH KEY (p_key) = p_value INTO me->st_table.

p_item = me->st_table.

CLEAR : me->st_table.

ENDMETHOD. "get_item_by_key

ENDCLASS. "lc_abnsample DEFINITION

************************************************************************
************************************************************************
* *
* PROGRAM FLOW LOGIC *
* *
************************************************************************

PARAMETERS : pa_key TYPE char12 DEFAULT 'ID', " Use : ID, NAME or PHONE
pa_value TYPE char12 DEFAULT 'AA'. " For ID Use :
" AA, BB or CC
" For NAME Use :
" NAME AA, NAME BB or NAME CC
" For PHONE Use :
" PHONE AA, PHONE BB or PHONE CC

START-OF-SELECTION.

DATA : olc_abnsample TYPE REF TO lc_abnsample,
o_data TYPE REF TO data.

FIELD-SYMBOLS : TYPE ANY,
TYPE ANY.

CREATE OBJECT olc_abnsample.

CREATE DATA o_data TYPE lc_abnsample=>ty_table_line.

IF olc_abnsample IS BOUND.

ASSIGN o_data->* TO .

olc_abnsample->get_item_by_key( EXPORTING p_key = pa_key
p_value = pa_value
IMPORTING p_item = ).

IF IS ASSIGNED AND IS NOT INITIAL.

DO.

ASSIGN COMPONENT sy-index OF STRUCTURE TO .

IF sy-subrc NE 0.

EXIT.

ELSE.

WRITE / : .

ENDIF.

ENDDO.

ELSE.

WRITE / : 'Filter not found in table'.

ENDIF.

UNASSIGN : .

ENDIF.

22/11/2010

Dependency Injection in ABAP OO

Introduction

Dependency Injection (DI) is a technique and a set of design patterns that enable us to develop loosely coupled code. Instead of directly instantiating concrete classes whenever we need to invoke a particular service, we program against interfaces. Instances of these interfaces are injected into the code by the external client so that the code can vary independently of the Dependency.

Here we will take a detailed look at the DI pattern known as Constructor Injection. Since it is a design pattern, I have chosen to present it in the formal design pattern style.

How do we guarantee that a necessary Dependency is always available to the class we are currently developing?

By requiring all callers to supply the Dependency as a parameter to the class' constructor.


REPORT ZADN_SAMPLE.

*----------------------------------------------------------------------*
* -> INTERFACE IF_LOG_PERSISTENCE
*----------------------------------------------------------------------*
INTERFACE if_log_persistence.

METHODS : save_log IMPORTING p_message TYPE char128.

ENDINTERFACE. "IF_LOG_PERSISTENCE

*----------------------------------------------------------------------*
* -> CLASS lc_log_in_email DEFINITION
*----------------------------------------------------------------------*
CLASS lc_log_in_email DEFINITION.

PUBLIC SECTION.

INTERFACES : if_log_persistence.

ENDCLASS. "lc_log_in_email DEFINITION

*----------------------------------------------------------------------*
* -> CLASS lc_log_in_email IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lc_log_in_email IMPLEMENTATION.

METHOD if_log_persistence~save_log.

WRITE / : 'LOG SEND BY EMAIL',
'-----------------',
p_message.

ENDMETHOD. "if_log_persistence~save_log

ENDCLASS. "lc_log_in_email IMPLEMENTATION

*----------------------------------------------------------------------*
* -> CLASS lc_log_in_file DEFINITION
*----------------------------------------------------------------------*
CLASS lc_log_in_file DEFINITION.

PUBLIC SECTION.

INTERFACES : if_log_persistence.

ENDCLASS. "lc_log_in_file DEFINITION

*----------------------------------------------------------------------*
* -> CLASS lc_log_in_file IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lc_log_in_file IMPLEMENTATION.

METHOD if_log_persistence~save_log.

WRITE / : 'LOG SEND TO FILE',
'-----------------',
p_message.

ENDMETHOD. "if_log_persistence~save_log

ENDCLASS. "lc_log_in_file IMPLEMENTATION

*----------------------------------------------------------------------*
* -> CLASS lc_log_in_database DEFINITION
*----------------------------------------------------------------------*
CLASS lc_log_in_database DEFINITION.

PUBLIC SECTION.

INTERFACES : if_log_persistence.

ENDCLASS. "lc_log_in_database DEFINITION

*----------------------------------------------------------------------*
* -> CLASS lc_log_in_database IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lc_log_in_database IMPLEMENTATION.

METHOD if_log_persistence~save_log.

WRITE / : 'LOG CREATE IN DATABASE TABLE',
'-----------------',
p_message.

ENDMETHOD. "if_log_persistence~save_log

ENDCLASS. "lc_log_in_database IMPLEMENTATION

*----------------------------------------------------------------------*
* -> CLASS LC_CALCULATOR DEFINITION
*----------------------------------------------------------------------*
CLASS lc_calculator DEFINITION.

PUBLIC SECTION.

METHODS : constructor IMPORTING p_log_target TYPE REF TO if_log_persistence,
div IMPORTING p_x TYPE i p_y TYPE i.

PRIVATE SECTION.

DATA : v_value TYPE i,
v_msg TYPE char128,
o_log TYPE REF TO if_log_persistence,
o_exp TYPE REF TO cx_sy_zerodivide.

ENDCLASS. "LC_CALCULATOR DEFINITION

*----------------------------------------------------------------------*
* -> CLASS LC_CALCULATOR IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lc_calculator IMPLEMENTATION.

METHOD constructor.

me->o_log = p_log_target.

ENDMETHOD. "CONSTRUCTOR

METHOD div.

TRY.

me->v_value = ( p_x / p_y ).

WRITE / : ' Division Operation = ', me->v_value.

CATCH cx_sy_zerodivide INTO me->o_exp.

me->v_msg = o_exp->get_text( ).

o_log->save_log( me->v_msg ).

ENDTRY.

ENDMETHOD. "DIV

ENDCLASS. "LC_CALCULATOR IMPLEMENTATION

************************************************************************
************************************************************************
* *
* PROGRAM FLOW LOGIC *
* *
************************************************************************

*----------------------------------------------------------------------*
* -> DEFINE SCREEN ELEMENTS
*----------------------------------------------------------------------*
PARAMETERS : p_ltype TYPE i DEFAULT 1. " Use 1, 2, 3 or 4
" with value of p_ltype

*----------------------------------------------------------------------*
* -> START-OF-SELECTION EVENT PROCESSING
*----------------------------------------------------------------------*
START-OF-SELECTION.

DATA : o_log_in_database TYPE REF TO lc_log_in_database,
o_log_in_file TYPE REF TO lc_log_in_file,
o_log_in_email TYPE REF TO lc_log_in_email,
o_calculator TYPE REF TO lc_calculator.

CASE p_ltype.

WHEN 1.

CREATE OBJECT o_log_in_database.

IF o_log_in_database IS BOUND.

CREATE OBJECT o_calculator
EXPORTING
p_log_target = o_log_in_database.

IF o_calculator IS BOUND.

o_calculator->div( EXPORTING p_x = 1 p_y = 1 ). " Sucess
o_calculator->div( EXPORTING p_x = 1 p_y = 0 ). " Error

ENDIF.

ENDIF.

WHEN 2.

CREATE OBJECT o_log_in_file.

IF o_log_in_file IS BOUND.

CREATE OBJECT o_calculator
EXPORTING
p_log_target = o_log_in_file.

o_calculator->div( EXPORTING p_x = 2 p_y = 1 ). " Sucess
o_calculator->div( EXPORTING p_x = 2 p_y = 0 ). " Error

ENDIF.

WHEN 3.

CREATE OBJECT o_log_in_email.

IF o_log_in_email IS BOUND.

CREATE OBJECT o_calculator
EXPORTING
p_log_target = o_log_in_email.

o_calculator->div( EXPORTING p_x = 3 p_y = 1 ). " Sucess
o_calculator->div( EXPORTING p_x = 3 p_y = 0 ). " Error

ENDIF.

WHEN OTHERS.

WRITE / 'NO IMPLEMENTATION ACTIVE FOR THIS LOG TYPE'.

ENDCASE.