This is a test message to test the length of the message box.
Login
|

040: Modern, solid and testable ABAP Code (Part 1)

214

The digital version of the betterCode presentation on modern and testable ABAP code. We'll look at software architecture and give tips for using ABAP Units.

Advertising


This is the first part of a multi-part series on modern, solid and testable ABAP code. The presentation was given in German at the betterCode event and is also available digitally in English.

 

Agenda

First, we will give a brief introduction and clarify what you can expect from this presentation. Then, we will discuss the topic of patterns and various design patterns that we use in modern development. After that, we will take a closer look at ABAP Units and the various patterns and possibilities. Finally, we will discuss various tips that help with automating the system landscape.

 

Introduction

In the introduction, we want to address the question: Why should we even bother with this topic anymore? The fundamental question is: Why do we still write ABAP code today? The modern ABAP stack now consists of SAP Fiori Elements for the user interfaces, data modeling via Core Data Services (CDS), and AI support that helps us generate the various components. So why code it ourselves? Isn't ABAP actually obsolete?

Let's take a closer look at the RAP stack. On the left, we see the entire data model. This basically consists of the table source, the Core Data Services, additional content for value helps, and the actual service. At the view level, we have the actual Fiori application, which is responsible for the visualization. On the right, you'll find the behavior and its implementation, which in turn contains the controller logic. Here, we're translating the data model into the MVC (Model-View-Controller) concept. While this isn't 100% accurate, it offers a good approach to classifying the various components of the model. Therefore, the controller remains very important. Since we're using ABAP code here, ABAP Unit is essential for testability and readability. We should consistently use clean ABAP; we'll discuss this in more detail later. Furthermore, we should maintain a clear structure and encapsulation to prevent the ABAP code from becoming unwieldy. Nothing is worse than an action implementation that contains over 500 lines of code in a single method. For this, we need clean encapsulation and appropriate objects that meaningfully divide this logic.

What can you actually expect from this presentation? Well, what you can't expect is basic training in ABAP OO or ABAP Unit. There are plenty of foundational courses that go much deeper into the details of the basics. However, you can expect to learn advanced techniques, such as various patterns and design patterns that we use to build testable code. Furthermore, you will receive an introduction to various approaches for creating and maintaining testable ABAP landscapes and regularly running automated tests.

 

Pattern

Let's therefore try to first delve into the different patterns. These are not all classic design patterns, but sometimes simply a certain way of using objects in the ABAP system. We always follow the same basic structure: We have a class that generates and stores a timestamp. The timestamp is made available as a public attribute after saving, so it can be used directly without having to use a corresponding getter or setter method. We will follow a chain of patterns that build upon each other. From the static class, through the instance class, to the interface definition, the factory method, and the factory itself. These patterns build upon each other in such a way that we will later get an overall impression of what has been specifically improved by each use. Finally, we will look at the Singleton, a special way of defining and using an object.

 

Static

The static class is the simplest pattern you can use. You've created a class where all methods and attributes are statically defined. This is essentially a function group. It's not ideal design, as we lack true reusability in the sense of object-oriented programming (like inheritance or polymorphism). However, we've effectively encapsulated the logic cleanly within an object. The actual attribute, the timestamp, is set to READ-ONLY. This ensures that we can read it from outside but cannot directly manipulate it. We leave the ability to change the value exclusively to the SAVE_TIMESTAMP method. The GET_TIMESTAMP method retrieves a current timestamp and returns it. We've created a separate class for its use, which you can also find in the demo material. Here, we call the SAVE_TIMESTAMP method, which retrieves a current timestamp and stores it in the class. We can read the timestamp via the public attribute and output it at the end. The catch is that the class isn't really flexible at the moment. Since it's static, we can't create independent instances, but always work with the same global state. So we can only store and process exactly one timestamp at a time.

 

Instance

Next, we'll look at the instance. The only difference from the previous version is that all definitions that started with CLASS-DATA or CLASS-METHODS have now been replaced by simple DATA and METHODS statements. Otherwise, we don't need to make any changes, but this gives us much broader possibilities. In the next step, let's look at how to use the class: We can now, for example, create a table of the class type in which we store different instances. In our example, we do this three times. We create a new instance each time using the NEW operator, call the logic, and store the respective timestamp. We then add this instance to our table. We get a table with three instances, each containing different timestamps. With this, we have overcome the global state of the static class.

 

Interface

As a first step, we create a new interface. An interface serves as a "blueprint" for a class. In this case, we can simply copy all the components of the class that were previously in the Public section and don't need to make any further changes to the definition. We now implement this interface in a new class. The corresponding definitions can then be found in the Public section. The method names change slightly, as the interface name is now part of the method name. To access a public method of the interface, we must always go through it. In this case, we use an alias for access. This allows us to use a shorter syntax for an attribute from the interface. However, we would not generally recommend this approach without reservation, as it makes searching for the original element within the code more difficult. In the next step, we create a new class with an initially empty implementation. For this, we include the interface in the class. The methods remain without logic at this stage. This approach allows us to create several different implementations of a single interface. These all outwardly have the same interface, but exhibit different behavior in detail.

How is all of this actually used? For this, we use an instance of the interface type and a table that holds various objects implementing the same interface. First, we instantiate the class with the interface for which we have a concrete implementation and append this object to the end of our instance table. In a further step, we can create an instance of the empty implementation in the same way. We can use the same variable to create the instances sequentially and add each one to the instance table. However, dealing with the different instances and interfaces presents a slight challenge. Since the interface defines the public interface, it primarily serves to work with the various objects, as all relevant methods and attributes are defined there. However, if we have an instance of the class type, we must explicitly access the interface, for example, to call a method like `save_timestamp`. This makes the call relatively long in the code. Alternatively, we could perform a cast. To do this, we define a reference variable of the interface type and assign the class object to it using a casting operator. While this shortens the actual method call, it requires the additional step of casting. Working with interfaces is therefore often a balancing act, as we either have to choose the long path via the interface components or ensure the corresponding target reference through a cast.

 

Outlook

In this episode, we have seen that ABAP and unit tests are still important parts of development, even though we now increasingly rely on RAP objects. To create clean and maintainable objects, we need some basic knowledge of object-oriented programming. Today, we started by exploring three of the typical basic instances of objects. In the next episode, we'll look at the extended design patterns and examine how they can be used effectively. Thanks for watching, and see you next time!

 

Further References:
YouTube - Part 1
GitHub - Examples


Included topics:
YouTubeScriptModernABAPClean ABAP
Comments (0)



And further ...

Are you satisfied with the content of the article? We post new content in the ABAP area every Tuesday and Friday and irregularly in all other areas. Take a look at our tools and apps, we provide them free of charge.


042: Modern, solid and testable ABAP Code (Part 3)

Category - YouTube

The digital version of the betterCode presentation on modern and testable ABAP code. We'll look at software architecture and give tips for using ABAP Units.

05/18/2026

041: Modern, solid and testable ABAP Code (Part 2)

Category - YouTube

The digital version of the betterCode presentation on modern and testable ABAP code. We'll look at software architecture and give tips for using ABAP Units.

05/11/2026

038: Recycling-Heroes - Annotations (Document)

Category - YouTube

In this episode, we'll look at the annotations in the Documents app and how to easily create them. We'll also extend the app and fix a problem with the key.

03/30/2026

037: Core Data Service [Basics] - View and View Entity

Category - YouTube

Let's take a look at the classic View in contrast to the modern View Entity. We'll discuss minor differences, migration to ABAP, and how you can manage Core Data Services more easily.

03/16/2026

036: Core Data Service [Basics] - Analysis

Category - YouTube

Where can you find more information about a Core Data Service in ABAP when it comes to analyzing existing objects? Let's look at various tools for this.

03/09/2026