ABAP Object Oriented with Model View Controller (MVC) – Part 1

This guide represents part 1 of 3 for the topic ABAP Object Oriented with Model View Controller (MVC).

  • Part 1: Understanding ABAP OO with MVC design using local classes.
  • Part 2: Expand local classes with functionality to better illustrate OO and MVC approach.
  • Part 3: Convert local classes into global classes.

Although object-oriented and model view controller design has existed for a long time, there are many ABAP developers who are still using procedural approach. I have involved in several projects in the US and Europe. Most of the clients now have strict requirements to use only object-oriented design.

More than 10 years ago, I first started with procedural design, and now for several years have been consistently using object-oriented design with MVC due to its advantage of reusability, maintainability and separation of business logic, data retrieval and user interface.

I could see the trend SAP is moving forward with object-oriented approach especially with newer technologies like SAP Fiori, AMDP and BOPF. Thus, it would be beneficial to adopt this approach.

MVC Design

On a high level overview, MVC consists of 3 components. The model, the view and the controller.

  • The model is where data selection happens.
  • The view is the interface users see on the screen i.e. selection screen, ALV and etc.
  • The controller interacts between the view and the controller, processing business logic requested by user from the view, request/update data from/to the database and facilitates output to the view.

Each of these components will be build into separate classes. Thus, allowing technical or even code-savvy functional consultants to easily locate what they are looking for. For example:

  • To identify what data are being selected, we just need to look into the model class.
  • To change the layout or ALV, we just need to look into view class.
  • To understand the business logic, we only need to look into controller class.

Let’s get started

In this guide, I’ll first explain the skeleton of the program utilizing object-oriented and MVC design and further expand it with some functionality to retrieve data, display in ALV and handle user command. I’ll not implement every single method as this guide’s main purpose is to showcase object-oriented and MVC concept.

These are the screenshots of program and objects we will build:

Selection screen

ALV

Custom structures

Message class

We will create 1 main program (report) and 4 local classes, with MVC design in mind as follows.

  • Main program: zlocal_oo
  • Model: cl_local_model
  • View: cl_local_scr, cl_local_ui
  • Controller: cl_local_app

Create main program zlocal_oo with includes. For a program that uses local classes (shown in this guide), I prefer to create a separate include for each MVC classes definition and implementation. I find that this approach is much cleaner, in contrast to dumping all class definition/implementation codes into a single include.

***********************************************************************
* REPORT         : ZLOCAL_OO
***********************************************************************
* SAPFlash
***********************************************************************
REPORT zlocal_oo MESSAGE-ID zmc.

*-----------------------------------------------------------------------
* INCLUDES
*-----------------------------------------------------------------------
INCLUDE:
  zlocal_oo_top, "Global data declarations
  zlocal_oo_scr, "Selection screen
  zlocal_oo_cd1, "Local class for application definition
  zlocal_oo_cd2, "Local class for data selection definition
  zlocal_oo_cd3, "Local class for UI definition
  zlocal_oo_ci1, "Local class for application implementation
  zlocal_oo_ci2, "Local class for data selection implementation
  zlocal_oo_ci3. "Local class for UI implementation

zlocal_oo_top contains all the global declarations.
cl_local_scr and cl_local_app will be instantiated at INITIALIZATION event block, while cl_local_model and cl_local_ui class will be instantiated within cl_local_app‘s constructor.

*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_TOP
*&---------------------------------------------------------------------*
*-----------------------------------------------------------------------
* CLASS
*-----------------------------------------------------------------------
CLASS:
  cl_local_app   DEFINITION DEFERRED,
  cl_local_model DEFINITION DEFERRED,
  cl_local_scr   DEFINITION DEFERRED,
  cl_local_ui    DEFINITION DEFERRED.

*-----------------------------------------------------------------------
* DATA DECLARATIONS
*-----------------------------------------------------------------------
DATA:
  r_scr    TYPE REF TO cl_local_scr,
  r_app    TYPE REF TO cl_local_app,

  g_soid   TYPE snwd_so_id.

zlocal_oo_scr contains the selection screen.

*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_SCR
*&---------------------------------------------------------------------*
SELECTION-SCREEN: BEGIN OF BLOCK b01 WITH FRAME TITLE text-001.
SELECT-OPTIONS: so_soid FOR g_soid.
PARAMETERS: p_curcd TYPE snwd_curr_code OBLIGATORY,
            p_lfcst TYPE snwd_so_lc_status_code.
SELECTION-SCREEN: END OF BLOCK b01.

SELECTION-SCREEN: BEGIN OF BLOCK b02 WITH FRAME TITLE text-012.
"Not used, it's an example to show dynamic screen modification
PARAMETERS: p_serve RADIOBUTTON GROUP g1 DEFAULT 'X' USER-COMMAND uc1,
            p_local RADIOBUTTON GROUP g1,
            p_lfile TYPE localfile MODIF ID md1.
SELECTION-SCREEN: END OF BLOCK b02.

zlocal_oo_cd1 contains local class-based exception with class definition of zcx_local_exc inheriting from cx_dynamic_check and contains controller with class definition of cl_local_app.

As you can see at the private visibility section of cl_local_app, I’m declaring 3 reference variables to the model and the view classes. As the controller cl_local_app interacts between the model and the view, it needs instance variables of the 3 mentioned classes (see below line 25-27).

*----------------------------------------------------------------------*
*       CLASS zcx_local_exc DEFINITION
*----------------------------------------------------------------------*
*       Class Definition for zcx_local_exc
*----------------------------------------------------------------------*
CLASS zcx_local_exc DEFINITION INHERITING FROM cx_dynamic_check.

  PUBLIC SECTION.
    INTERFACES if_t100_dyn_msg.
    ALIASES msgty FOR if_t100_dyn_msg~msgty.
ENDCLASS.
*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_CD1
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS cl_local_app DEFINITION
*----------------------------------------------------------------------*
*       Class Definition for cl_local_app
*----------------------------------------------------------------------*
CLASS cl_local_app DEFINITION FINAL.

  PUBLIC SECTION.

    METHODS:
      constructor                IMPORTING
                                   ir_scr TYPE REF TO cl_local_scr,
      at_selection_screen_output,
      at_selection_screen,
      start_of_selection,
      end_of_selection.

  PRIVATE SECTION.

    DATA:
      mr_scr       TYPE REF TO cl_local_scr,
      mr_model     TYPE REF TO cl_local_model,
      mr_ui        TYPE REF TO cl_local_ui.
ENDCLASS.

zlocal_oo_cd2 contains model with class definition of cl_local_model.

*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_CD2
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS cl_local_model DEFINITION
*----------------------------------------------------------------------*
*       Class Definition for cl_local_model
*----------------------------------------------------------------------*
CLASS cl_local_model DEFINITION FINAL.
ENDCLASS.

zlocal_oo_cd3 contains view with class definitions of cl_local_scr and cl_local_ui.

*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_CD3
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS cl_local_scr DEFINITION
*----------------------------------------------------------------------*
*       Class Definition for cl_local_scr
*----------------------------------------------------------------------*
CLASS cl_local_scr DEFINITION FINAL.
ENDCLASS.
*----------------------------------------------------------------------*
*       CLASS cl_local_ui DEFINITION
*----------------------------------------------------------------------*
*       Class Definition for cl_local_ui
*----------------------------------------------------------------------*
CLASS cl_local_ui DEFINITION FINAL.
ENDCLASS.

zlocal_oo_ci1 contains controller with class implementation of cl_local_app.

As you can see from the constructor method below, both cl_local_model and cl_local_ui classes are instantiated here. cl_local_scr instance reference variable is an input parameter here. Since cl_local_app is the controller, it requires access to model and view. Thus, model and view classes are instantiated here to create object references.

*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_CI1
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS cl_local_app IMPLEMENTATION
*----------------------------------------------------------------------*
*       Class Implementation for cl_local_app
*----------------------------------------------------------------------*
CLASS cl_local_app IMPLEMENTATION.
*&---------------------------------------------------------------------*
*&      CONSTRUCTOR
*&---------------------------------------------------------------------*
*       Constructor for creating initial data references
*----------------------------------------------------------------------*
*      -->IR_SCR  Ref to selection screen object
*----------------------------------------------------------------------*
  METHOD constructor.
    mr_scr   = ir_scr.
    mr_model = NEW cl_local_model( ).
    mr_ui    = NEW cl_local_ui( ).
  ENDMETHOD.
*&---------------------------------------------------------------------*
*&      AT_SELECTION_SCREEN_OUTPUT
*&---------------------------------------------------------------------*
*       Event for at selection screen output
*----------------------------------------------------------------------*
  METHOD at_selection_screen_output.
  ENDMETHOD.
*&---------------------------------------------------------------------*
*&      AT_SELECTION_SCREEN
*&---------------------------------------------------------------------*
*       Event for at selection screen
*----------------------------------------------------------------------*
  METHOD at_selection_screen.
  ENDMETHOD.
*&---------------------------------------------------------------------*
*&      START_OF_SELECTION
*&---------------------------------------------------------------------*
*       Event for data selection and main process
*----------------------------------------------------------------------*
  METHOD start_of_selection.
  ENDMETHOD.
*&---------------------------------------------------------------------*
*&      END_OF_SELECTION
*&---------------------------------------------------------------------*
*       Event for end of selection
*----------------------------------------------------------------------*
  METHOD end_of_selection.
  ENDMETHOD.
ENDCLASS.

zlocal_oo_ci2 contains model with class implementation of cl_local_model.

*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_CI2
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS cl_local_model IMPLEMENTATION
*----------------------------------------------------------------------*
*       Class Implementation for cl_local_model
*----------------------------------------------------------------------*
CLASS cl_local_model IMPLEMENTATION.
ENDCLASS.

zlocal_oo_ci3 contains view with class implementations of cl_local_scr and cl_local_ui.

*&---------------------------------------------------------------------*
*&  Include           ZLOCAL_OO_CI3
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS cl_local_scr IMPLEMENTATION
*----------------------------------------------------------------------*
*       Class Implementation for cl_local_scr
*----------------------------------------------------------------------*
CLASS cl_local_scr IMPLEMENTATION.
ENDCLASS.
*----------------------------------------------------------------------*
*       CLASS cl_local_ui IMPLEMENTATION
*----------------------------------------------------------------------*
*       Class Implementation for cl_local_ui
*----------------------------------------------------------------------*
CLASS cl_local_ui IMPLEMENTATION.
ENDCLASS.

Since we have completed all the required class definitions and implementations skeletons, we shall continue to complete the event blocks as follows.

INITIALIZATION event block is mainly used to set initial default values to selection screen.

*-----------------------------------------------------------------------
* INITIALIZATION
*-----------------------------------------------------------------------
INITIALIZATION.
  IF NOT r_scr IS BOUND.
    r_scr = NEW cl_local_scr( ).
  ENDIF.

  IF NOT r_app IS BOUND.
    r_app = NEW cl_local_app( r_scr ).
  ENDIF.

AT SELECTION-SCREEN OUTPUT caters for dynamically modify screen appearance i.e. hiding/displaying screen elements or enable/disable input fields.

*-----------------------------------------------------------------------
* AT SELECTION-SCREEN OUTPUT
*-----------------------------------------------------------------------
AT SELECTION-SCREEN OUTPUT.
  r_app->at_selection_screen_output( ).

AT SELECTION-SCREEN ON VALUE-REQUEST is required when we need to implement F4 search help.

*-----------------------------------------------------------------------
* AT SELECTION-SCREEN ON VALUE-REQUEST
*-----------------------------------------------------------------------
AT SELECTION-SCREEN ON VALUE-REQUEST FOR so_soid-low.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR so_soid-high.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_lfile.

AT SELECTION-SCREEN ON is useful when we need to validate user input at selection screen fields. Fields with error will remain enabled while other fields will be disabled.

*-----------------------------------------------------------------------
* AT SELECTION-SCREEN ON
*-----------------------------------------------------------------------
  "Checks selection screen fields. Fields with error will remain enabled
  "while other fields will be disabled.
AT SELECTION-SCREEN ON p_curcd.

AT SELECTION-SCREEN event block is usually catered for authorization checks. The difference between AT SELECTION-SCREEN and AT SELECTION-SCREEN ON validation behavior is that AT SELECTION-SCREEN will not disable any selection screen fields in case of error.

*-----------------------------------------------------------------------
* AT SELECTION-SCREEN
*-----------------------------------------------------------------------
AT SELECTION-SCREEN.
  r_app->at_selection_screen( ).

START-OF-SELECTION is for the main processing of the program.

*-----------------------------------------------------------------------
* START-OF-SELECTION
*-----------------------------------------------------------------------
START-OF-SELECTION.
  r_app->start_of_selection( ).

END-OF-SELECTION is only intended for use in programs where logical database are associated, according to SAP. However, it is still widely used for output list / ALV purposes.

*-----------------------------------------------------------------------
* END-OF-SELECTION
*-----------------------------------------------------------------------
END-OF-SELECTION.
  r_app->end_of_selection( ).

This section contains premium content accessible by paid members only. Please click here to join our membership to support us.

For premium members, please login below to access this content.