Many ABAP source codes clearly show signs of having been modified repeatedly over the years. The code bears the signatures of different developers. The result, to put it positively, is a hodgepodge of different styles, or to put it negatively, pure chaos.
It’s difficult to follow the original idea behind the code — if there ever was one. Particularly striking examples of this can be found in reports, print programs, and especially customer enhancements.
Keep changes to existing code to a minimum
This brings me directly to the core of this post. Extensions to existing code, for example to implement new functionalities, should be designed so that they increase the size of the existing code, measured in lines, as little as possible at the point where they are called. It’s important to note that this refers to the amount of code at the point where the new functionality is called. The functionality itself can consist of any amount of code.
This recommendation has been regularly ignored in the past. Changes were simply implemented on the spot, even if they were 200 lines long. As a result, the original code has been stretched more and more over the years, ultimately leading to the infamous “spaghetti code.” However, this only describes its appearance, and very few people would find the sight of spaghetti unpleasant.
The spaghetti code is literally quite complex, as it sequentially performs a large number of individual tasks. Because it has a large, task-independent local and global context, it utilizes various variables, structures, and tables — after all, its visibility grants it access to almost all memory contents.
As a reader, it’s virtually impossible to discern which algorithm is using which data to perform a self-contained task. Moreover, the sheer monolith of code is daunting. In other words, one doesn’t even dare attempt its analysis, because as a developer, you can practically feel the impending cognitive strain, which quickly leads to exhaustion.
A better approach
We all know the better approach. Concepts like divide-and-conquer, single-responsibility principle, separation of concerns and modularization practically force us in the right direction.
A new feature is a distinct concept. This requires at least one dedicated class (with an interface) and unit tests. There can also be multiple classes, but only one of them provides access to or serves as the bridge to the new functionality.
This single class is then integrated into the existing code at the point where the new functionality is needed. This has several positive effects, including:
- The code is written in classes. These are independent, reusable development objects with their own data management (if necessary).
- The classes are given unit tests. This ensures their correct functionality and simultaneously documents usage examples.
- Instead of using the classes directly, interfaces are used. This allows for the replacement of a class if necessary.
- Classes, interfaces, methods, and attributes contribute to the clarity of the new functionality through their names.
- The bridge from the old code to the new code is established via the clear signature of a method call. Ideally, this involves exactly one method call. This makes it easy to see what input the new code requires and what it returns. It also provides a good location for a “break point”.
- Error handling in the old code can be implemented in only one place, namely after the single method call.
In short: don’t follow your first impulse and just write code in between or in addition. A little design already brings many positive aspects that prevent software erosion, but ultimately don’t eliminate it.
Thank you for reading. If you enjoyed the post, please share the article with your community. Thanks in advance.
Michael (a mind forever voyaging)
