Part I
Architectural Design Patterns
In this chapter, we’ll get to know one of the most fundamental design patterns of the entire software industry: MVC. Countless commercial applications are built with MVC, and there is no reason why your ABAP application shouldn’t take advantage of this time-proven pattern. If you are building a GUI-based application, MVC can isolate the application logic.
1 MVC
The model–view–controller design pattern, or MVC design pattern, focuses on isolating the application logic from the GUI-related code. Generally, MVC is one of the most fundamental design patterns in the entire range. MVC is so common that some development tools even have MVC project types. If you were to learn a single design pattern and use it for the rest of your life, it would be MVC. During training sessions, MVC also happens to be one of the first design patterns demonstrated.
Traditional MVC suggests an approach where you divide your application into three pieces:
- Model (”M”)
Class(es) that contain your application logic. A model class shouldn’t contain any code related to GUI operations. In the ABAP world, the model class would correspond to your backend classes in Transaction SE24. - View (”V”)
Class(es) that contain your GUI-related stuff. Textboxes, combo boxes, forms, etc. are all in this category. In the ABAP world, the view may correspond to your SAP List Viewer (ALV) grid, Web Dynpro ABAP components, etc. In a typical project, we reuse elements provided by SAP and don’t code views from the scratch. - Controller (”C”)
The client application that binds the model and view together. In the ABAP world, the controller would correspond to your executable application in Transaction SE38.
Let’s move forward and see MVC in action, beginning with a case study before moving on to other patterns. Whatever additional pattern you might use, MVC will probably be the most fundamental pattern of any GUI application.
1.1 Case Study: Read, Process, Display, and Post
Our case study will be one of the most common ABAP requirements ever—a typical CRUD-like application (create, read, update, delete). Our program needs to get data from somewhere, do some calculations, display the result with ALV, and post something to the database when the user clicks a button. We all have likely written such an application a thousand times.
To make it more concrete, we’re going to use an example where we need to do the following:
- Read: Read customer orders from tables VBAK and VBAP.
- Process: Eliminate orders of blocked customers.
- Display: Show results using ALV.
- Post: Create delivery documents for selected items.
Using classic ABAP, we could develop a program in Transaction SE38, which would roughly look like the code in Listing 1.1.
REPORT zrep.
” Some data definitions
” Some selection-screen parameters
START-OF-SELECTION.
PERFORM read_orders.
PERFORM eliminate_blocked.
PERFORM display_alv.
END-OF-SELECTION.
FORM read_orders.
” Some code to read VBAK, VBAP, etc
ENDFORM.
FORM eliminate_blocked.
” Some code to read KN* tables and remove entries from the ITAB
ENDFORM.
FORM display_alv.
” Some code to call REUSE_ALV_GRID_DISPLAY
ENDFORM.
FORM user_command USING rucomm rs_selfield.
CHECK rucomm EQ c_ucomm_save.
PERFORM create_dlv.
ENDFORM.
FORM create_dlv.
” Some code to loop through the ITAB & create deliveries
ENDFORM.
” Some further forms
Listing 1.1 Simple Application in Transaction SE38
So far, so good. We have created a typical program structure encountered frequently among thousands of SAP clients. However, this typical structure has a major flaw: Code for database operations is mixed with code for managing the GUI. The database logic is locked inside Transaction SE38 and is not reusable.
To see how this can cause problems, imagine that a new requirement has emerged that says that we need to include an RFC function (remote function call). The RFC is supposed to get order numbers from an external system, eliminate blocked clients, and create deliveries for whatever remains. Basically, we want the same application logic in the form of an RFC function.
To take this example a step further, an additional requirement could be to write a new GUI using Web Dynpro ABAP targeting web users without SAP GUI.
What can be done in classical ABAP is very limited and blunt, as you can see with the following options:
- You could simply copy and paste the code from Transaction SE38 to Transaction SE37. However, this is not the best idea. Why? If, for instance, you need to modify the blocked customer elimination logic or add a new field to the BAPI, you would need to modify multiple spots.
- You could take advantage of include files so forms are available everywhere. Not an elegant solution, because the data shared between forms would need to be defined in Transaction SE37/SE38 multiple times. If you need to add a new field to the internal table, you need to modify multiple spots.
- You could create a huge function group and turn forms into functions. This option is better than the others, but you wouldn’t be taking advantage of object-oriented features, such as polymorphism, inheritance, and encapsulation. See Appendix C for more information on these advantages.
Instead, we can turn our gaze to the design patterns and see what MVC can do for us. As we saw at the start of chapter, MVC tells us to split the application into three compo...