My comment about the importance of ABAP naming conventions to Thorsten Franz' blog Great Programmers will their Code to the new Guy triggered an interesting discussion about naming conventions for ABAP. The opinions range from "...is important" to "...We do not advise you on naming conventions, do whatever you want".
The latter statement sounds like a capitulation. This resignation might be due to the following questions:
- Are there useful naming conventions for ABAP? Apparently not even SAP has them.
- Do naming conventions really improve ABAP coding and how?
- How can we check the compliance of ABAP program objects with the naming conventions?
ABAP Naming Conventions: "Yes, we exist"
I started my SAP career more than 10 years ago at Cirrus Consulting. The very first thing I got there was a comprehensive documentation about ABAP naming and programming conventions which they had created for one of their biggest customers. And at the Zürcher Kantonalbank they had such a document, too.
Admittedly there were deviations from these conventions in particular because many external developers worked at these customers and the Code Inspector (SCI) was not yet available at that time. Nevertheless these conventions facilitated the readability of the coding and the handing over (for maintenance) to other developers. And if you look carefully around you will realize that even SAP (or at least a subset of its developers) uses naming conventions.
Now let us imagine a "...do whatever you want" customer where a developer creates a report (containing a constant for the speed of light) which in the subsequent years has been maintained by three other developers. Three of them use their own naming conventions and the forth one uses none at all so we may end up with the following representations of a single constant:
- GC_LIGHTSPEED or LC_LIGHTSPEED
The forth developer may replace all previous representations with his own SPEED_OF_LIGHT without any prefix because everybody "knows" that this is a (pyhsical) constant. This medley of naming conventions will definitely confuse every developer. And this is just a simple example considered with the mixing up the naming of global and local variables.
In the following section I will present my own naming conventions which are a "best-of-breed" blend of SAP naming conventions and those of my previous employers.
Call a Spade a Spade
Naming conventions must be concise, short and distinct. Any ambiguity is a burden for maintenance in the future. Using three categories of criteria it is possible to unambigously name virtually all variables and most signature parameters:
- Visibility: Global / Local / Class Context
- Type: Field / Structure / Table Type / Reference / Constants
- Structural Context: FORM routines / Function Modules / Methods
There are two general naming conventions:
- Variables and Class Attributes: <Visibility>_<Type>_<Description>
- Signature Parameters: <Structural Context>_<Type>_<Description>
Visibility & Type
We have three kinds of visibility: Global, Local and Class Context (which includes Interfaces as well) and seven different types (see below).
|Global||G||Field||D||GD_MATNR||DATA: gd_matnr TYPE matnr.|
|Structure||S||GS_KNB1||DATA: gs_knb1 TYPE knb1.|
|Table Type||T||GT_VBAK||DATA: gt_vbak TYPE TABLE OF vbak.|
DATA: go_grid TYPE REF TO cl_gui_alv_grid.
DATA: go_msglist TYPE REF TO if_reca_message_list.
|Data Object||DO||GDO_DATA||DATA: gdo_data TYPE REF TO data.|
|Constant||C||GC_LIGHTSPEED||CONSTANTS: gc_lightspeed TYPE i VALUE '300000'.|
|Local||L||Field||D||LD_MATNR||DATA: ld_matnr TYPE matnr.|
|Structure||S||LS_KNB1||DATA: ls_knb1 TYPE knb1.|
|Table Type||T||LT_VBAK||DATA: lt_vbak TYPE TABLE OF vbak.|
DATA: lo_grid TYPE REF TO cl_gui_alv_grid.
DATA: lo_msglist TYPE REF TO if_reca_message_list.
|Data Object||DO||LDO_DATA||DATA: ldo_data TYPE REF TO data.|
|Constant||C||LC_LIGHTSPEED||CONSTANTS: lc_lightspeed TYPE i VALUE '300000'.|
|Class Context||M||Field||D||MD_MATNR||DATA: md_matnr TYPE matnr.|
|Structure||S||MS_KNB1||DATA: ms_knb1 TYPE knb1.|
|Table Type||T||MT_VBAK||DATA: mt_vbak TYPE TABLE OF vbak.|
DATA: mo_grid TYPE REF TO cl_gui_alv_grid.
DATA: mo_msglist TYPE REF TO if_reca_message_list.
|Data Object||DO||MDO_DATA||DATA: mdo_data TYPE REF TO data.|
|Constant||C||MC_LIGHTSPEED||CONSTANTS: mc_lightspeed TYPE i VALUE '300000'.|
The vast majority of variables within program objects are either global or local. And in the future there will be a remarkably shift towards class attributes (ABAP-OO). Thus, assigning a unique prefix to each group makes their visibility unambigous for every developer.
Class attributes (instance and static) are special because they are global within the class/instance whereas they appear local from outside the class/instance. Without referring to a class(name) or instance these attributes are "hidden" (i.e. local).
Question: Does the type prefix offer any benefit?
In ABAP forum posts you may find the following definitions for ALV grid instances:
- GRID: global (?), local (?), class context (?); class reference (?)
- G_ALV_GRID: global (!?), local (?), class context (?); class reference (!?)
- GO_GRID: global class reference OUTSIDE any class context (my naming convention)
Answer: Yes, because we meet the developer's expectation and anticipation.
You may argue: What a big fuss about such a little subtlety. My answer to this is: Every SAP developer who comes across a GO_GRID variable in any of my programs knows in advance(!) the meaning and scope of it.
Structural Context (1): FORM routine Signature
The SAP system does not care about which kind of formal parameters (USING or CHANGING) are used in FORM routine signatures. Both kinds of formal parameters can be changed within the routine and the modified contents transferred back to the calling program. This is ambiguity at its worst.
In order to make the signature of a FORM routine clear as crystal we define every Input = USING parameter and every Output = CHANGING parameter. Within the FORM routine all USING parameters should be regarded as "constants" meaning that they are not changed nor is any change transferred back to the calling program.
|Parameter||Prefix ||Type||Prefix||Example |
Again, by defining Input = USING (prefix 'U') and Output = CHANGING (prefix 'C') we meet the developer's expectation and alleviate understanding of the FORM routine.
Structural Context (2): Function Module Signature
The same logic applies to function modules parameters. In addition, we can facilitate the understanding of TABLES parameters (Yes, I know they are obsolete yet some still like to use 'em) by the semantics of their Input/Output behaviour:
- IT_ITAB = Input only
- ET_ITAB = Output only
- XT_ITAB = Input & Output
|Parameter||Prefix ||Type||Prefix||Example |
Of course there is no technical difference whatsoever between "Importing", "Exporting" and "Changing" TABLES parameters. Yet the different naming gives the developer already an idea about the function of this module without looking into the coding. Or in other words: Try to "express" the function of the module already in its signature.
Structural Context (3a): Method Signature
The logic explained above is just applied to method parameters as well and extended to the additional RETURNING parameters of methods.
|Parameter||Prefix ||Type||Prefix||Example |
Structural Context (3b): Static vs. Instance Attributes
Static attributes are special because they exist only once for all instances of this class. Modifying a static attribute within a given instance makes this change visible to all other instances. Both types of attributes have the prefix 'M' (class context) in my naming convention. In order to distinguish between static and instance attributes I apply the following convention:
- Instance Attribute: with self-reference me-> (e.g. me->md_key)
- Static Attribute: without self-reference (.e.g. ms_row)
You can find an example of this naming convention in the coding of INCLUDE ZRSWBOSDR_C01 in my blog Multi-Purpose ALV Programming.
Another unambigous convention is to drop the self-reference prefix and use the full qualified name for static attributes:
- Instance Attribute: md_key (with or with self-reference prefix)
- Static Attribute: lcl_eventhandler=>ms_row
We can apply the same naming conventions even to field-symbols which makes them much more readable and understandable for every developer. This is particularly important because the contents of field-symbols cannot be analyzed statically but is only determined at runtime.
SAP and Lego
Why has Lego become one of the world's most famous toys? Part of the answer can be found here:
"Lego pieces of all varieties are a part of a universal system. \ Despite variation in the design and purpose of individual pieces over \ the years, each remains compatible in some way with existing pieces. \ Lego bricks from 1958 still interlock with those made in 2009, and Lego \ sets for young children are compatible with those made for teenagers.
\ Bricks, beams, axles, mini figures, and all other parts in the Lego \ system are manufactured to an exacting degree of precision. When \ snapped together, pieces must have just the right amount of strength \ and flexibility mixed together to stick together. They must stay \ together until pulled apart. They cannot be too easy to pull apart, or \ the resulting constructions would be unstable; they also cannot be too \ difficult to pull apart, since the disassembly of one creation in order \ to build another is part of the Lego appeal. In order for pieces to \ have just the right "clutch power", Lego elements are manufactured \ within a tolerance of 2 µm."
QUESTION: "Have you ever seen a child which sits in front of a pile of Lego bricks claiming it can't build anything because all bricks have the same size???"
For me SAP is just an incredibly huge pile of Lego bricks (for grown-ups). Consistent naming conventions are an indispensable standard which enables us to manufacture long-lasting developments that are easy to understand and maintain (pull apart and reassemble).
Code Inspector: Check Compliance with your Naming Conventions
The Code Inspector (transaction SCI) provides you with all means to check compliance with your naming conventions. Within the check variant you an explicit check Programming Conventions.
Looking at the check Naming Conventions a popup appears where you can define your conventions for data variables and signatures (FORM routine, function module, classes).
Since I have not yet mentioned macros (DEFINE) yet here is my convention:
- MAC_<description>: e.g. mac_suppress_toolbar_btn
Another set of frequently used global variables are (select-)parameters and select-options:
S_MATNR FOR mara-matnr.
P_MATKL TYPE matkl.
Looking at the check Extended Naming Conventions for Programs you will find my 7 types (Field, Structure, Table Type, Class, Interface, Data Object, Constant) grouped into 5 prefixes:
- Elementary Type includes Field and Constant
- Object Reference includes Class and Interface
The prefixes shown above are the default values when opening the check with which I do not agree. For example, the prefix "R" indicates a global range according to my conventions:
DATA: rt_matnr TYPE RANGE OF matnr.
It is possible to define useful naming conventions for ABAP. Naming conventions significantly help in understanding a program and navigating around it. Both the new and the senior guy will benefit in particular when it comes to maintenance because they can focus their analysis on the program logic and not the "logic" of the previous developer.
Naming conventions are not impositions for creative developers but, on the contrary, side rails for long-lasting development.
I no longer think it makes sense to explicitly distinguish between classes and interfaces because at the end of the day you always work with an interface implementing class (even if the static type is that of an interface). Therefore, the two separate rows for "Class" and "Interface" have been merged.