ABAP Strategy Design Pattern
Summary: In this tutorial, you will learn how to implement ABAP strategy design pattern with a practical example.
Problem
Sometimes when you enhance a report, class, or include, you have to pay a lot of efforts and time to do regression test on the whole process in SAP. There is a case that when you change one part, other parts are broken..Oop! To avoid such situations, the application should be designed to follow a dominant object oriented design known as open-closed principle. The program should be designed in the way that it is open for extension and closed for modification to eliminate the impact on existing logic. In design pattern, you use strategy pattern to design the application to follow this open-closed principle.
Intent
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Strategy Design Pattern UML Diagram
The classes and/or objects are participating in the strategy design pattern are:
- Strategy
- The strategy interface defines methods that represent common algorithms. The context uses the strategy interface to call the algorithms implemented by ConcreteStrategy.
- ConcreteStrategy
- implements the alogrithm defined in the strategy interface.
- Context
- Context object contains a reference to a stratgey object. The context object delegates requests from client to the strategy object.
ABAP Strategy Design Pattern Implementation
In ABAP programming, you often have to create interface between SAP system and non-SAP systems. One of the most common uses interface is File. You can extract data from SAP to files in CSV or tab-delimited format. The file then can be downloaded in to local PC or put it to the file server for further processing by non-SAP system.
We can use strategy design pattern to design our program as UML below:
Explaination of interfaces and classes in the digram above:
- IF_EXTRACTABLE is equipvalent to Strategy
- CLI_FILE_CLIENT, CL_FILE_SERVER are equipvalent to ConcreteStrategy
- CL_APP is equivalent to Context
Suppose in the future you have a new requirement to send the file via email to a distribution list, you just have to create another class called CL_FILE_EMAIL that implements the interface IF_EXTRACTABLE. Nothing needs to change except the logic handle email in client. This is called open closed principle in object oriented design. The Strategy design pattern supports “open for extension” but “closed for modification”. All the code for handling file extract to local PC and server are unchanged and therefore elimitating the effort for regression test on these parts.
Let’s take a look a the ABAP code implementation.
Interface IF_EXTRACTABLE contains only one method called extract:
*----------------------------------------------------------------------* * INTERFACE if_extractable *----------------------------------------------------------------------* * ~ Strategy *----------------------------------------------------------------------* INTERFACE if_extractable. METHODS: extract. ENDINTERFACE. "if_extractable
The CL_FILE_CLIENT and CL_FILE_SERVER classes that implements IF_EXTRACTABLE interface:
*----------------------------------------------------------------------* * CLASS cl_file_client DEFINITION *----------------------------------------------------------------------* * ~ConcreteStrategy *----------------------------------------------------------------------* CLASS cl_file_client DEFINITION. PUBLIC SECTION. INTERFACES: if_extractable. ALIASES: extract FOR if_extractable~extract. ENDCLASS. "cl_file_client DEFINITION *----------------------------------------------------------------------* * CLASS cl_file_client IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS cl_file_client IMPLEMENTATION. METHOD extract. WRITE: 'Save file to the local PC'. ENDMETHOD. "extract ENDCLASS. "cl_file_client IMPLEMENTATION *----------------------------------------------------------------------* * CLASS cl_file_server DEFINITION *----------------------------------------------------------------------* * ~ConcreteStrategy *----------------------------------------------------------------------* CLASS cl_file_server DEFINITION. PUBLIC SECTION. INTERFACES: if_extractable. ALIASES: extract FOR if_extractable~extract. ENDCLASS. "cl_file_server DEFINITION *----------------------------------------------------------------------* * CLASS cl_file_server IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS cl_file_server IMPLEMENTATION. METHOD extract. WRITE: 'Save file to the server'. ENDMETHOD. "extract ENDCLASS. "cl_file_server IMPLEMENTATION
Next we implement Context class:
*----------------------------------------------------------------------* * CLASS cl_app DEFINITION *----------------------------------------------------------------------* * ~Context *----------------------------------------------------------------------* CLASS cl_app DEFINITION. PUBLIC SECTION. METHODS: constructor IMPORTING im_extractable TYPE REF TO if_extractable, process_output. PRIVATE SECTION. DATA: mo_extractable TYPE REF TO if_extractable. ENDCLASS. "cl_app DEFINITION *----------------------------------------------------------------------* * CLASS cl_app IMPLEMENTATION *----------------------------------------------------------------------* * *----------------------------------------------------------------------* CLASS cl_app IMPLEMENTATION. METHOD constructor. mo_extractable = im_extractable. ENDMETHOD. "constructor METHOD process_output. IF mo_extractable IS NOT INITIAL. mo_extractable->extract( ). ENDIF. ENDMETHOD. "process_output ENDCLASS. "cl_app IMPLEMENTATION
Finally we can develop a program to test our classes:
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001. PARAMETERS: pa_local TYPE c RADIOBUTTON GROUP pout, pa_servr TYPE c RADIOBUTTON GROUP pout. SELECTION-SCREEN END OF BLOCK b1. DATA: go_app TYPE REF TO cl_app, go_extract TYPE REF TO if_extractable. START-OF-SELECTION. CASE 'X'. WHEN pa_local. CREATE OBJECT go_extract TYPE cl_file_client. WHEN pa_servr. CREATE OBJECT go_extract TYPE cl_file_server. ENDCASE. CREATE OBJECT go_app EXPORTING im_extractable = go_extract. go_app->process_output( ).
In this tutorial, you’ve learned how to implement ABAP strategy design pattern that allows defining a family of related algorithms, encapsulate each individual one and make them interchangable in term of client uses.







