Proxy acts on behalf of some other objects. When working with Proxies, as name suggest, you work with another object rather than actual object. Lets checkout Proxy design pattern implementation in ABAP.
What is a Proxy?
Sometimes, you need to delay the instantiation of the object may be because its too costly to instantiate or it is not needed till certain point of time. You want to instantiate the object only after the basic validations. So, what you do is create an abstract layer in between the Client and object in the question. This abstract layer or the object is a proxy.
Proxy object only instantiate the object when it is required. If the object is not needed, it would not be created. Once the object is created, all the future operations would be carried over on the “Real” object instead of on the proxy object. Both – proxy and real – objects would implement the same interface. Thus both object can perform same operations seamlessly. Also the proxy object can pass all the signature to the real object.
UML
I’ll use this UML to demonstrate the Proxy design pattern.
There are the components involved in the UML.
- LIF_DATA – This interface provides common behavior with common interface. This is also referred as Subject. Since both Proxy & Real object would implement the subject, proxy can easily take place instead of the Real object.
- LCL_PROXY_DATA – This class implements the Subject Interface. This also has an attribute O_T100_DATA which is a real object. This also controls how the real object is instantiated. If the real object is instantiated, proxy object would call the respective behavior of the real object. This is a Proxy Object.
- LCL_T100_DATA – This class also implements the subject interface. This class contains all the business logic. This is called Real Object. Proxy will instantiate the real object and call the respective methods.
Code Lines
Here are the code lines to achieve Proxy in ABAP:
Proxy Design Patterns
REPORT znp_dp_proxy. * INTERFACE lif_data. DATA: t_t100 TYPE tt_t100. METHODS: get_data IMPORTING iv_spras TYPE spras OPTIONAL CHANGING ct_data TYPE tt_t100. METHODS: write_data. ENDINTERFACE. "lif_data * CLASS lcl_proxy_data DEFINITION. PUBLIC SECTION. INTERFACES: lif_data. PRIVATE SECTION. DATA: o_t100_data TYPE REF TO lif_data. ENDCLASS. "lcl_proxy_Data DEFINITION * CLASS lcl_t100_data DEFINITION. PUBLIC SECTION. INTERFACES: lif_data. ENDCLASS. "lcl_t100_Data DEFINITION * CLASS lcl_proxy_data IMPLEMENTATION. METHOD lif_data~get_data. * validations IF iv_spras NE sy-langu. EXIT. ENDIF. * Authority check * some other check * instantiate "Real" Object CREATE OBJECT o_t100_data TYPE lcl_t100_data. o_t100_data->get_data( EXPORTING iv_spras = iv_spras CHANGING ct_data = ct_data ). ENDMETHOD. "lif_data~get_data METHOD lif_data~write_data. IF o_t100_data IS NOT BOUND. WRITE:/ 'No data to display'. ELSE. o_t100_data->write_data( ). ENDIF. ENDMETHOD. "lif_data~write_Data ENDCLASS. "lcl_proxy_Data IMPLEMENTATION * CLASS lcl_t100_data IMPLEMENTATION. METHOD lif_data~get_data. * This process takes very long time to * get the data. You can imagine this happening * when accessing big tables without index. SELECT * FROM t100 INTO TABLE lif_data~t_t100 UP TO 20 ROWS WHERE sprsl = iv_spras. ct_data = lif_data~t_t100. ENDMETHOD. "lif_data~get_data METHOD lif_data~write_data. DATA: lv_lines TYPE i. lv_lines = LINES( lif_data~t_t100 ). WRITE: / 'Total lines',lv_lines. ENDMETHOD. "lif_data~write_Data ENDCLASS. "lcl_t100_Data IMPLEMENTATION * CLASS lcl_main_app DEFINITION. PUBLIC SECTION. CLASS-METHODS: run. ENDCLASS. "lcl_main_app DEFINITION * CLASS lcl_main_app IMPLEMENTATION. METHOD run. DATA: lo_proxy TYPE REF TO lif_data. DATA: lt_data TYPE tt_t100. * CREATE OBJECT lo_proxy TYPE lcl_proxy_data. lo_proxy->get_data( EXPORTING iv_spras = 'D' CHANGING ct_data = lt_data ). lo_proxy->write_data( ). * CREATE OBJECT lo_proxy TYPE lcl_proxy_data. lo_proxy->get_data( EXPORTING iv_spras = sy-langu CHANGING ct_data = lt_data ). lo_proxy->write_data( ). ENDMETHOD. "run ENDCLASS. "lcl_main_app IMPLEMENTATION * START-OF-SELECTION. lcl_main_app=>run( ).
Design Time Consideration
You should consider these step while implementing the Proxy design pattern.
- Create an interface or an Abstract class based on the requirement of the Subject.
- Implement the Interface to create a real subject
- Implement the interface to create a Proxy object. Make sure all the validation or all the operations which may not execute the real business logic. Once the object is created, simply call the methods of the real subject.
Check out all Design Patterns
You may also want to explore all other Design Patterns in OO ABAP.
- ABAP Object Design Patterns – Singleton
- ABAP Objects Design Patterns – Model View Controller (MVC) Part 1
- ABAP Objects Design Patterns – Model View Controller (MVC) Part 2
- ABAP Objects Design Patterns – Model View Controller (MVC) Part 3
- ABAP Objects Design Patterns – Decorator
- ABAP Objects Design Patterns – Factory Method
- ABAP Objects Design Patterns – Observer
- Case Study: Observer Design Pattern Usage
- ABAP Objects Design Patterns – Abstract Factory
- OO Design Pattern Decorator – Why do we need to use helper variable?
- ABAP Objects Design Patterns – Facade
- ABAP Objects Design Patterns – Adapter
- ABAP Objects Design Patterns – Composite
- ABAP Objects Design Patterns – Iterator
- Iterator Design Pattern to access Linked List in ABAP Objects
- ABAP Objects Design Patterns – Proxy
- ABAP Objects Design Patterns – Prototype
- ABAP Objects Design Patterns – Singleton Factory
- ABAP Object Oriented Approach for Reports – Initial Design
- ABAP Object Oriented Approach for Reports – Redesign
- ABAP Objects Design Patterns – Builder
- ABAP Objects Design Patterns Singleton Usage
- ABAP MVC – Model View Controller Discussion
- Object Oriented Approach for Reports with multiple Datasource
- OO ABAP – Selection Object with Direct Access
- OO ABAP – Selection Criteria Object using RS_REFRESH_FROM_SELECT OPTIONS
- ABAP Factory Method Using SWITCH