Sie sind auf Seite 1von 12

ABAP Objects Design Patterns - Model View Controller (MVC)

y y

Added by Naimesh Patel, last edited by Naimesh Patel on Oct 14, 2008 (view change)

Model View Controller design pattern is used to make our Business logic separate from the output of the information generated from Business Logic. Usually, we call this design patterns as the MVC. Here Business logic is the Model; Output of the data is the View and the link which connects the Business logic to output is the Controller. MVC is useful when user have to select the output type or data representation type e.g. Report, Grid or List, Charts - barchart, pie chart, and so on. In this type of application, we can create a MODEL class and put our business logic into it which will be isolated from the way output is being generated. Controller class will control the information flow between the Model and Views. All the types of data representation can be created in different View classes. In turn, this view will access the Controller and than Controller will provide the data to View. You can follow this link for more information on MVC: 1. ABAP Objects Design Patterns - Model View Controller (MVC) Part 1 - In this part you can find the introduction on the MVC 2. ABAP Objects Design Patterns - Model View Controller (MVC) Part 2 - In this part you will find how we can implement the MVC in ABAP using the ABAP objects (Model and Controller) 3. ABAP Objects Design Patterns - Model View Controller (MVC) Part 3 - In the continuation with the example on implementing the MVC (Views)
ABAP Objects Design Patterns - Model View Controller (MVC) Part 1 Posted by Naimesh Patel at 8:09 PM Labels Design Patterns

Share 0 inShare Today we will discuss about the Design Pattern: Model-View-Controller, which is also very famous by its abbriviation MVC. By definition, MVC is to isolate the business logic from the User Interface which gives great degree of flexibility to change business logic independently to the user interface and vice versa. In MVC, User Interface acts as the View; Business logic acts as the Model and the link which provides the

link between the View and Model is known as the Controller. In real time business, MVC is used anywhere, where users have a choice to select his or her view. For example, Windows Media Player, Gmail or Yahoo mail and so on. All these type of applicaiton provides us the option to select the skin as per our choice. Let's take an example: We have to develop one Sales report for our corporate intranet. This report must have the option to display the sales data in the classical report format; different charts - pie, bar, line or both - report & chart and it must be based on the User's choice. This type of requirements where we can easily separate the Business logic and the views are the best candidates for MVC. Generally, Model sends the data to controller and controller will pass that data to Views and views will display the data as per their nature. In SAP, our business logic(model) will not send data unless and untill View request for an data becase ABAP is event driven language. Like user has to run some transaction to get the data, means application view has to initiate the process and ask for the data from the Model. In this requesting process, Controller will help the view to be apart from the model. UML diagram of the typical MVC application would be:

As we can see here, Model will send the data to the Controller and controller will pass that information to the View. Now, its a view's responsibility to create a user specific view - Report, or Chart.

Advantages: Since both our business logic and view logic are different, we can easily change any of the logic without interepting the other part.

Monday, October 13, 2008


ABAP Objects Design Patterns - Model View Controller (MVC) Part 2 Posted by Naimesh Patel at 8:41 PM

Labels Design Patterns

Share 0 inShare In this post, we will see how we can implement the MVC (Model-View-Controller) design pattern in ABAP using the Objects. If you have not read the previous discussion about MVC: ABAP Objects Design Patterns - Model View Controller (MVC) Part 1, than I strongly recommond to read that before moving forward. To implement the MVC, we will create two applications - One will generate an output in ALV and other will generate an output Smartforms. We will put our business logic in the MODEL class. We will create one CONTROL class to establish control between Model and Views. The UML diagram for any of the application would be like:

Our business logic for this example is fairly simple - select the Sales Orders from the VBAK which were created in last ten days. The public method GET_DATA in the class ZCL_MODEL will act as the business logic. Additionally, this class has the public attribute T_VBAK which will be set by the GET_DATA and hold our data from the table. Model Method Definition

Model Attribute definition

Code Snippet of method GET_DATA


* Parameters * Importing IR_ERDAT TYPE TPMY_R_DATE Ranges for date * METHOD get_data. * * Get data and save into attribute T_VBAK SELECT * FROM vbak INTO TABLE t_vbak WHERE erdat IN ir_erdat. * * ENDMETHOD.

Our controller class ZCL_CONTROL will have a method GET_OBJECT which will give us an object of the model class. We require a public attribute which can refer to the object created in the method GET_OBJECT. Controller Method definition:

Controller Attributes definition:

Code Snippet for method GET_OBJECT


* Parameters * Importing IF_NAME TYPE CHAR30 Model class name * METHOD get_object . * DATA: lo_object TYPE REF TO object. * * Generic object reference to importing class CREATE OBJECT lo_object TYPE (if_name). IF sy-subrc = 0. * Downcasting to assign generic object to O_MODEL o_model ?= lo_object. ENDIF. * ENDMETHOD.

Monday, October 13, 2008


ABAP Objects Design Patterns - Model View Controller (MVC) Part 3 Posted by Naimesh Patel at 10:00 PM Labels Design Patterns

Share 0 inShare In this post, we will see how we can implement the Views which will access the Controller and model which is encapsulated in the controller. This post is in continuation of previous post: ABAP Objects Design Patterns - Model View Controller (MVC) Part 2. For our first Application view will be ALV output. To get the data for the ALV into the application, we will

use the reference of the MODEL class created in the Controller. This way our model class is entrily separated by the view. Code Snippet for View 1 (ALV) of MVC design
*&---------------------------------------------------------------------* * REPORT ztest_mvc_alv. * START-OF-SELECTION. *--------* Controller *--------DATA: lo_control TYPE REF TO zcl_control. * * Iniiate controller CREATE OBJECT lo_control. * * Get the object from Control CALL METHOD lo_control->get_object EXPORTING if_name = 'ZCL_MODEL'. * *--------* Model - Business Logic *--------* Date Range DATA: r_erdat TYPE RANGE OF vbak-erdat, la_erdat LIKE LINE OF r_erdat. * la_erdat-sign = 'I'. la_erdat-option = 'BT'. la_erdat-low = sy-datum - 10. la_erdat-high = sy-datum. APPEND la_erdat TO r_erdat. * * Get data method CALL METHOD lo_control->o_model->get_data EXPORTING ir_erdat = r_erdat. * *--------* View - ALV output *--------DATA: lo_alv TYPE REF TO cl_salv_table. * DATA: lx_msg TYPE REF TO cx_salv_msg. TRY. cl_salv_table=>factory( IMPORTING r_salv_table = lo_alv CHANGING t_table = lo_control->o_model->t_vbak ).

CATCH cx_salv_msg INTO lx_msg. ENDTRY. * * * Displaying the ALV lo_alv->display( ).

Our Second application is fairly simple once we have implemented the first application. In this application only part which differs is calling the Smartform. Code Snippet for View 1 (Smartforms) of MVC design
*&---------------------------------------------------------------------* * REPORT ztest_mvc_view_2_ssf. * START-OF-SELECTION. *--------* Controller *--------DATA: lo_control TYPE REF TO zcl_control. * * Iniiate controller CREATE OBJECT lo_control. * * Get the object from Control CALL METHOD lo_control->get_object EXPORTING if_name = 'ZCL_MODEL'. * *--------* Model - Business Logic *--------* Date Range DATA: r_erdat TYPE RANGE OF vbak-erdat, la_erdat LIKE LINE OF r_erdat. * la_erdat-sign = 'I'. la_erdat-option = 'BT'. la_erdat-low = sy-datum - 10. la_erdat-high = sy-datum. APPEND la_erdat TO r_erdat. * * Get data method CALL METHOD lo_control->o_model->get_data EXPORTING ir_erdat = r_erdat. * *---------

* View - Smartform Output *--------* Smartform FM DATA: l_form TYPE tdsfname VALUE 'ZTEST_MVC_VIEW_2', l_fm TYPE rs38l_fnam. * CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME' EXPORTING formname = l_form IMPORTING fm_name = l_fm EXCEPTIONS no_form =1 no_function_module = 2 OTHERS = 3. * * calling Smartform FM DATA: ls_control TYPE ssfctrlop. " Controlling info DATA: ls_composer TYPE ssfcompop. " Output info * CALL FUNCTION l_fm EXPORTING control_parameters = ls_control output_options = ls_composer user_settings = ' ' t_vbak = lo_control->o_model->t_vbak EXCEPTIONS formatting_error = 1 internal_error = 2 send_error =3 user_canceled = 4 OTHERS = 5. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF.

Let's say, in future we enhanced the business logic model class and now we want to implement for the business. In this case, we just have to change the object reference created in the Controller and we are good to go. Obviously, we have to take care of the newly created methods or methods which parameters are enhanced. ABAP Object Design Patterns: Singleton Posted by Naimesh Patel at 8:10 PM Labels ABAP, Code, Design Patterns, Objects

Share

0 inShare Today we will try to explore the design patterns in the ABAP Objects. We will start with the Singleton design pattern, which is the simplest of its family of design patterns. UPDATE:This blog post has been updated with clear example demo on 12/17/2009. So, there could be some comments which would be obsolete. What is the concept of the Singleton design pattern? The concpet of restricting the instantiation of the a class to only and only to one object is called Singleton. As name suggests, it will restrict to create only one instance of a class. The calss will have a logic in place which will deny if the application will ask for more than one instance. Let's try to understand with an example: We have an application which will bring the pay stub of an employee for current month. In a standarad system, there will be only one active salary account for the employee with the company. Because of this fact, we should only create one object of the employee's salary account. In program, we are creating this object in a loop. So, what happens if we don't have a design pattern which will restrict it to create more than one object. Application will create, rather overwrite an instance of the class. In ABAP, generally we check if the instance is created or not, like: Code Snippet to check instance

*&---------------------------------------------------------------------* DATA: lo_application TYPE REF TO lcl_application. IF lo_application IS BOUND. CREATE OBJECT lo_application. ENDIF.

But, if we take another reference to the class and create a instance of that, it will definatly allow. So, we need to have Singleton design pattern implemented. How to implement Singleton design Pattern in ABAP? We can use the CLASS-DATA(static data) to save the created instance within the class and check with that instance, if application asks for a new instance.

We will look at this example.

UML diagrm for the example:

Code Snippet

*&---------------------------------------------------------------------* *& Report shows how to use the static data of the class to *& implement the design patterns. *&---------------------------------------------------------------------* REPORT ztest_singleton_pattern. * *----------------------------------------------------------------------* * CLASS lcl_application DEFINITION *----------------------------------------------------------------------* CLASS lcl_application DEFINITION CREATE PRIVATE. * PUBLIC SECTION. * Static Method which will return us the object reference CLASS-METHODS: get_apps_instance RETURNING value(ro_apps) TYPE REF TO lcl_application. * METHODS: set_v_name IMPORTING iv_name TYPE char30, get_v_name RETURNING value(rv_name) TYPE char30. * PRIVATE SECTION. * static class reference to hold the existing object reference CLASS-DATA: lo_apps TYPE REF TO lcl_application. * DATA: v_name TYPE char30. * ENDCLASS. "lcl_application DEFINITION * * *----------------------------------------------------------------------* * CLASS lcl_application IMPLEMENTATION

*----------------------------------------------------------------------* CLASS lcl_application IMPLEMENTATION. * * This method will return the object reference to the calling application METHOD get_apps_instance. IF lo_apps IS INITIAL. * creation of the object CREATE OBJECT lo_apps. ENDIF. * assigning reference back to exporting parameter ro_apps = lo_apps. ENDMETHOD. "get_apps_instance * METHOD set_v_name. me->v_name = iv_name. ENDMETHOD. "set_v_name * METHOD get_v_name. rv_name = me->v_name. ENDMETHOD. "get_v_name * ENDCLASS. "lcl_application IMPLEMENTATION * * START-OF-SELECTION. * *.Reference: 1 ......................................... DATA: lo_application TYPE REF TO lcl_application. DATA: lv_result TYPE char30. * WRITE: / 'LO_APPLICATION: '. * calling the method which gets us the instance * Statement CREATE OBJECT LO_APPLICATION * would not work as the class LCL_APPLICATION instantiation * is set to PRIVATE lo_application = lcl_application=>get_apps_instance( ). * Set the variable and get it back. lo_application->set_v_name( 'This is first Object' ). lv_result = lo_application->get_v_name( ). WRITE: / lv_result. CLEAR lv_result. * *.Reference: 2............................................ DATA: lo_2nd_apps TYPE REF TO lcl_application. SKIP 2. WRITE: / 'LO_2ND_APPS : '. * calling the method which gets us the instance * By calling GET_APPS_INSTANCE method again to get the singleton * object, it would give the same object back and assign it to * LO_2ND_APPS object reference. This would be varified by * getting the value of the instance attribute V_NAME lo_2nd_apps = lcl_application=>get_apps_instance( ). lv_result = lo_2nd_apps->get_v_name( ). WRITE: / lv_result. CLEAR lv_result.

This will generate the output like this: