How to implement Strategy pattern in ABAP Objects?
I have a problem where I need to implement different algorithms, depending on the type of input. Example: I have to calculate a Present Value, sometimes with payments in advance, sometimes payment in arrear.
From documentation and to enhance my ABAP Objects skills, I would like to implement the strategy pattern. It sounds the right solution for the problem.
Hence I need some help in implementing this pattern in OO. I have some basic OO skills, but still learning.
Has somebody already implemented this pattern in ABAP OO and can give me some input. Or is there any documentation how to implement it?
Thanks and regards,
Marcin Pciak replied
Keshav has already outlined required logic, so let me fulfill his answer with a snippet
INTERFACE lif_payment. METHODS pay CHANGING c_val TYPE p. ENDINTERFACE.
CLASS lcl_payment_1 DEFINITION. PUBLIC SECTION. INTERFACES lif_payment. ALIASES pay for lif_payment~pay. ENDCLASS. CLASS lcl_payment_2 DEFINITION. PUBLIC SECTION. INTERFACES lif_payment. ALIASES pay for lif_payment~pay. ENDCLASS. CLASS lcl_payment_1 IMPLEMENTATION. METHOD pay. "do something with c_val i.e. c_val = c_val - 10. ENDMETHOD. ENDCLASS. CLASS lcl_payment_2 IMPLEMENTATION. METHOD pay. "do something else with c_val i.e. c_val = c_val + 10. ENDMETHOD.
Main class which uses strategy pattern
CLASS lcl_main DEFINITION. PUBLIC SECTION. "during main object creation you pass which payment you want to use for this object METHODS constructor IMPORTING ir_payment TYPE REF TO lif_payment. "later on you can change this dynamicaly METHODS set_payment IMPORTING ir_payment TYPE REF TO lif_payment. METHODS show_payment_val. METHODS pay. PRIVATE SECTION. DATA payment_value TYPE p. "reference to your interface whcih you will be working with "polimorphically DATA mr_payment TYPE REF TO lif_payment. ENDCLASS. CLASS lcl_main IMPLEMENTATION. METHOD constructor. IF ir_payment IS BOUND. me->mr_payment = ir_payment. ENDIF. ENDMETHOD. METHOD set_payment. IF ir_payment IS BOUND. me->mr_payment = ir_payment. ENDIF. ENDMETHOD. METHOD show_payment_val. WRITE /: 'Payment value is now ', me->payment_value. ENDMETHOD. "hide fact that you are using composition to access pay method METHOD pay. mr_payment->pay( CHANGING c_val = payment_value ). ENDMETHOD. ENDCLASS.
PARAMETERS pa_pay TYPE c. "1 - first payment, 2 - second DATA gr_main TYPE REF TO lcl_main. DATA gr_payment TYPE REF TO lif_payment. START-OF-SELECTION. "client application (which uses stategy pattern) CASE pa_pay. WHEN 1. "create first type of payment CREATE OBJECT gr_payment TYPE lcl_payment_1. WHEN 2. "create second type of payment CREATE OBJECT gr_payment TYPE lcl_payment_2. ENDCASE. "pass payment type to main object CREATE OBJECT gr_main EXPORTING ir_payment = gr_payment. gr_main->show_payment_val( ). "now client doesn't know which object it is working with gr_main->pay( ). gr_main->show_payment_val( ). "you can also use set_payment method to set payment type dynamically "client would see no change if pa_pay = 1. "now create different payment to set it dynamically CREATE OBJECT gr_payment TYPE lcl_payment_2. gr_main->set_payment( gr_payment ). gr_main->pay( ). gr_main->show_payment_val( ). endif.