Building a Flexible Validation Framework in ABAP
Building a Flexible Validation Framework in ABAP
One of the recurring challenges in ABAP development is handling data validation. At first, it looks simple: a couple of checks on a structure or an internal table, maybe three or four conditions. But as the project grows, validation logic tends to expand into large, unstructured blocks of code that are hard to maintain, search through, enable/disable, or extend for new requirements.
To solve this, I designed a universal validation tool that can be plugged into different projects. The goal was to make it possible to validate data of different structures and domains without rewriting the same boilerplate over and over again.
The solution is based on three components:
  1. Validator – class that executes validation logic.
  2. Message Processor – class that collects and formats validation messages.
  3. Status Processor – will be developed later as part of the same framework.
Additionally we have a customizing table as a storage of validations.
Each component is isolated in terms of configuration and implementation. They can be used individually if needed, but also work together as part of a validation “constructor”.

Class Structure and Customizing Table
Here is the scheme how class’s structure is arranged and how customizing table can be used.
The Validator
At the core is class zvu_cl_validator, which implements interface zvu_if_validate with method validate.
Data for validation is passed via a property container object (zvu_cl_prop_container), which follows the “property container” pattern. This ensures flexible parameter passing across various checks without tight coupling to a specific structure.
Validation rules are stored in a configuration table zvu_tt_valcust.
Depending on the rule setup, the validator supports three modes:
  • Simple check – condition from the config table is parsed and executed (e.g., field is not initial).
  • Custom check – a method of a validator subclass is called (business-specific rules).
  • Complex check – a dedicated checker class implementing zvu_if_check and its method check is invoked.
This split allows for maximum flexibility. Custom checks live only in validator subclasses, so the base class stays clean and generic (e.g., universal checks like “field not empty”).
The code can be checked via the link FlexibleValidationFramework.git.
Design Patterns in Use
  • Chain of Responsibility: used in checker classes where multiple checks can be chained depending on configuration.
  • Property Container: for passing validation input data and parameters.
Two approaches for invoking validations are supported:
  1. Interface-driven checks – ensures consistency but generates many small classes.
  2. Method-by-name invocation – less boilerplate, but requires strict adherence to parameter conventions.
Both approaches are supported, depending on the configuration in zvu_tt_valcust.
Example: Business Validation Rules
Suppose we are validating a structure with fields:
id, herkl (country of origin), endland (destination country), kunnr (customer)
The validation rules might be:
  1. Country of origin exists in a reference table → complex check in a separate class.
  2. Destination country is filled → simple check.
  3. Origin ≠ Destination → simple check.
  4. Customer exists and is valid → custom check method in a partner validator subclass.
The base validator supports all three variants (simple, custom, complex).
For testing, custom checks are implemented only in a subclass (e.g., zvu_cl_export_validator), without polluting the main class.
Message Processor
After each check, we need to handle validation messages. Each validation should result in exactly one message in the system variable.
  • For complex/custom checks, the message can be raised directly in the method or checker class.
  • For simple checks, the message can be specified in the config table.
The validator calls zvu_if_message_processor→collect_message, which gathers all messages into a common log.
The base implementation:
  • collect_message – collects messages into a local table.
  • release_log – outputs or persists the log. By default, nothing is stored; subclasses can implement persistence (e.g., saving to BALLOG).
The message processor object is stored as a protected attribute of the validator, so subclasses can inject their own implementations.
Status Processor (Planned)
The status processor component is not yet designed. It will be developed later and integrated with the existing validator and message processor. The idea is to handle data statuses after validation, providing another layer of control and feedback.
Why This Matters
This design is meant as a template: a starting point that can be reused or adjusted for different projects.
With this approach you can:
  • Reuse a single validation framework across very different projects.
  • Add, remove, or adjust validation rules without touching the core logic.
  • Switch between lightweight (simple) checks and full-blown business rules (complex/custom).
  • Keep logs and messages consistent and centrally controlled.
Instead of growing into unreadable blocks of hardcoded IF statements, validation becomes structured, configurable, and extensible.
The full implementation of this framework is available on GitHub: https://github.com/JuliaBerteneva/FlexibleValidationFramework.git.
Feel free to comment, share your thoughts, or suggest improvements — I’d be glad to hear your feedback.
Made on
Tilda