Why OOP and Design Patterns Matter in ABAP
An introduction to a practical series
Photo by Alex wong on Unsplash
ABAP systems are rarely short-lived.
They evolve over years or even decades, pass through multiple teams, and are continuously extended to support new business requirements. In such an environment, code quality is not about elegance - it is about survivability.
This is where Object-Oriented Programming (OOP) and design patterns become essential tools rather than theoretical concepts.
Design patterns provide proven solutions to recurring design problems. In ABAP, they help developers manage complexity while keeping systems extensible, readable, and testable - without breaking existing behavior.

SAP itself relies heavily on patterns across its frameworks (RAP, BOPF, UI frameworks, service layers). Writing custom code that follows similar principles makes it easier to:
→ integrate with SAP standards,
→ onboard new developers,
→ refactor safely,
→ and extend functionality without rewriting large parts of the system.
Well-chosen patterns help to:
→ reduce coupling,
→ improve readability,
→ support automated testing,
→ and keep custom developments aligned with SAP’s architectural direction.

This article is the foundation for a series of posts where we will look at concrete design patterns in ABAP, their typical use cases, and real implementation examples. Before diving into individual patterns, it is important to align on the fundamentals they are built on.
OOP Principles as the Foundation for Patterns
Design patterns do not exist in isolation.
They only make sense when built on solid OOP principles. Without these fundamentals, patterns often degrade into unnecessary abstractions or overengineering.
Encapsulation
Encapsulation means controlling how data is accessed and modified.
A class should protect its internal state and expose behavior through methods, not through direct attribute access.

In ABAP, encapsulation is implemented using visibility sections:
PRIVATE
Accessible only within the class itself.
Used to hide implementation details and protect data integrity.
PROTECTED
Accessible within the class and its subclasses.
Typically used for shared technical behavior or extension points.
PUBLIC
Accessible from outside the class.
Defines the official contract of the class.

Best practice in ABAP:
Public attributes should be avoided unless they represent immutable data. Instead, state changes should go through methods that enforce business rules and keep the object consistent.
Encapsulation is the first step toward maintainable and refactor-friendly code.
Abstraction
Abstraction focuses on separating what a component does from how it does it.
The goal is to make business logic depend on capabilities, not on concrete implementations.

In ABAP, abstraction is achieved through:
Interfaces (IF_*) - define what must be done, without any implementation
Abstract classes (ABSTRACT) - define a partial implementation or workflow, leaving specific steps open

Interfaces are especially important because they:
→ decouple callers from implementations,
→ enable dependency injection,
→ allow clean mocking in unit tests.

Abstract classes are often used when:
→ a workflow is fixed,
→ but individual steps vary per use case.
Abstraction is the foundation for extensibility and testability in ABAP systems.
Inheritance
Inheritance allows a class to reuse behavior from another class by extending it.
Inheritance is commonly used to:
→ define a shared workflow,
→ reuse technical logic (logging, validation hooks, error handling),
→ provide controlled extension points.

Best practice in ABAP:
Inheritance should be used sparingly and intentionally.
Deep inheritance hierarchies are discouraged because they:
→ hide behavior across multiple levels,
→ increase coupling,
→ make debugging and refactoring harder.
Polymorphism
Polymorphism allows different implementations to be used interchangeably behind a common interface or superclass.
This means:
→ the caller works with an interface,
→ the concrete implementation is selected at runtime,
→ behavior changes without changing the calling code.

In ABAP, polymorphism is achieved through:
→ implementing interfaces,
→ redefining methods in subclasses.

Polymorphism is essential for design patterns, including:
Factory - returning different implementations behind one interface
Strategy - switching algorithms (e.g. XML vs CSV processing)
Template Method - varying steps within a fixed workflow
Testing - replacing real implementations with test doubles
Without polymorphism, extensibility often degrades into large CASE statements and tightly coupled code.
Abstract Classes as Containers of Common Behavior
One of the most common and effective OOP techniques in ABAP is the use of abstract base classes to encapsulate shared workflows.
When to use abstract base classes:
→ when there is shared logic,
→ but not all steps can be implemented generically.

A typical structure looks like this:
CLASS zcl_base_service DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS execute.
  PROTECTED SECTION.
    METHODS validate ABSTRACT.
    METHODS save ABSTRACT.
ENDCLASS.
CLASS zcl_order_service DEFINITION
  INHERITING FROM zcl_base_service.
  PROTECTED SECTION.
    METHODS validate REDEFINITION.
    METHODS save REDEFINITION.
ENDCLASS.
Here, the base class defines the workflow, while subclasses provide concrete implementations for specific steps.
Why this approach works well in ABAP:
→ clear separation of workflow vs implementation,
→ controlled extension points,
→ very common in SAP standard code,
→ natural foundation for the Template Method pattern.
Dependency Injection and Testability
As soon as code becomes modular, testability becomes a first-class concern.
Dependency Injection (DI) means that a class receives its dependencies from the outside instead of creating them internally. This allows logic to be tested in isolation.
Instead of this:
mo_logger = NEW zcl_logger( ).
Prefer passing dependencies explicitly:
METHOD method1.
  mo_logger = io_logger.
ENDMETHOD.
This approach enables:
→ replacement of real implementations with test doubles,
→ isolation from databases and external APIs,
→ usage of the ABAP Test Double Framework.
In later posts, we will look at how DI is applied in practice when testing patterns such as Singleton, Factory, and Strategy.
What Comes Next in This Series
This post intentionally stays conceptual.
In the next articles, we will focus on concrete patterns frequently used in ABAP, including:
→ Singleton (and how to test it safely),
→ Factory (also Factory Method and Abstract Factory),
→ Property Container,
→ Strategy,
→ Template Method,
→ and real refactoring examples from productive systems.
Disclaimer
Patterns are not goals by themselves.
They are tools for managing complexity in long-running SAP systems. The real skill is not knowing every pattern - but recognizing recurring problems and choosing the right abstraction at the right time.
Made on
Tilda