ABAP Core Part 10: Clean ABAP Basics for Maintainable Code
Write ABAP others can maintain: meaningful names, small methods, classes over includes and FORMs, modern syntax, no magic values, clear error handling, unit tests and automated checks — with a before/after refactoring.
Explanation
📌 KEY POINTS
✅ Code is read far more often than written — optimize for the reader.
✅ Small methods with one purpose, descriptive names, no magic values.
✅ Classes and methods instead of FORM routines and global variables.
💡 Let tools help: ATC and code inspector, ABAP Unit, ADT quick fixes, pretty printer.
━━━━━━━━━━━━━━━━━━━━
▶ WHERE WE ARE
Parts 1–9 taught the language. This final part is about writing it well. SAP's open-source "Clean ABAP" style guide is the reference; here are the basics every developer should apply.
━━━━━━━━━━━━━━━━━━━━
▶ 1. NAMES
- Descriptive: calculate_free_seats( ) instead of calc( ); flights_of_airline instead of lt_tab1.
- Consistent prefix convention per team (or none in small methods).
- Booleans read like questions: is_full, has_bookings.
━━━━━━━━━━━━━━━━━━━━
▶ 2. SMALL, FOCUSED UNITS
- One method = one task; typically fits on one screen.
- Split long reports: selection → read → process → output in separate methods of a local class.
- Avoid deep nesting (more than 3 levels); return early.
━━━━━━━━━━━━━━━━━━━━
▶ 3. MODERN SYNTAX
- On 7.40+ systems, Clean ABAP also recommends newer syntax (inline declarations, VALUE, string templates) — follow your project's release and team guideline; the principles apply equally to classic code.
- ABAP SQL with @ host variables, comma-separated field lists, INTO at the end.
- Avoid obsolete statements (FORM/PERFORM in new code, MOVE, TABLES in classes, header lines, OCCURS).
━━━━━━━━━━━━━━━━━━━━
▶ 4. NO MAGIC VALUES
Constants or enumerations (TYPES BEGIN OF ENUM) for status codes and fixed values.
━━━━━━━━━━━━━━━━━━━━
▶ 5. ERRORS
Exceptions in reusable code, messages at the UI layer, never swallow errors (Parts 8–9).
━━━━━━━━━━━━━━━━━━━━
▶ 6. TESTABILITY
Separate logic from database access and UI so logic can be tested with ABAP Unit; use test doubles for data access (see Modularization and OOP topics).
━━━━━━━━━━━━━━━━━━━━
▶ 7. TOOLS
- ATC / Code Inspector — static checks (performance, security, obsolete syntax).
- ABAP Unit — automated tests (Ctrl+Shift+F10 in ADT).
- Pretty printer (Shift+F1) and ADT quick fixes (Ctrl+1): extract method, rename, declare inline.
━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP
Compare the before and after versions in the code example: same result, but the "after" version is readable, testable and changeable. Apply the same steps to one of your own old reports.
✅ CHECKPOINT: you can recognize and write clean ABAP. ABAP Core complete — next topic: Internal Tables.
Code example
* ===== BEFORE: hard to read, hard to test =====* REPORT zold.* DATA: itab TYPE TABLE OF sflight, wa TYPE sflight, cnt TYPE i.* PARAMETERS p1 TYPE s_carr_id.* SELECT * FROM sflight INTO TABLE itab WHERE carrid = p1.* LOOP AT itab INTO wa.* IF wa-seatsocc >= wa-seatsmax. cnt = cnt + 1. ENDIF.* ENDLOOP.* IF cnt > 5. WRITE 'X'. ENDIF. * ===== AFTER: clean, classic ABAP =====REPORT zflight_capacity_report. PARAMETERS p_carr TYPE s_carr_id OBLIGATORY. TYPES ty_flights TYPE STANDARD TABLE OF sflight. CLASS lcl_capacity_report DEFINITION. PUBLIC SECTION. CONSTANTS c_alert_threshold TYPE i VALUE 5. " no magic number METHODS run IMPORTING iv_airline TYPE s_carr_id. METHODS count_full_flights " pure logic -> unit-testable IMPORTING it_flights TYPE ty_flights RETURNING VALUE(rv_full) TYPE i. PRIVATE SECTION. METHODS read_flights IMPORTING iv_airline TYPE s_carr_id RETURNING VALUE(rt_flights) TYPE ty_flights.ENDCLASS. CLASS lcl_capacity_report IMPLEMENTATION. METHOD run. DATA: lt_flights TYPE ty_flights, lv_full TYPE i. lt_flights = read_flights( iv_airline ). lv_full = count_full_flights( lt_flights ). IF lv_full > c_alert_threshold. WRITE: / 'Alert:', lv_full, 'fully booked flights for', iv_airline. ELSE. WRITE: / lv_full, 'fully booked flights for', iv_airline. ENDIF. ENDMETHOD. METHOD read_flights. SELECT * FROM sflight INTO TABLE rt_flights WHERE carrid = iv_airline. ENDMETHOD. METHOD count_full_flights. DATA ls_flight TYPE sflight. LOOP AT it_flights INTO ls_flight WHERE seatsocc >= seatsmax. rv_full = rv_full + 1. ENDLOOP. ENDMETHOD.ENDCLASS. DATA go_report TYPE REF TO lcl_capacity_report. START-OF-SELECTION. CREATE OBJECT go_report. go_report->run( p_carr ). * ===== ABAP Unit test for the logic (test class in the same program) =====CLASS ltc_capacity DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. PRIVATE SECTION. METHODS counts_only_full FOR TESTING.ENDCLASS. CLASS ltc_capacity IMPLEMENTATION. METHOD counts_only_full. DATA: lo_cut TYPE REF TO lcl_capacity_report, lt_flights TYPE ty_flights, ls_flight TYPE sflight, lv_full TYPE i. ls_flight-seatsmax = 100. ls_flight-seatsocc = 100. APPEND ls_flight TO lt_flights. ls_flight-seatsmax = 100. ls_flight-seatsocc = 50. APPEND ls_flight TO lt_flights. CREATE OBJECT lo_cut. lv_full = lo_cut->count_full_flights( lt_flights ). cl_abap_unit_assert=>assert_equals( act = lv_full exp = 1 ). ENDMETHOD.ENDCLASS. * 💡 Modern syntax (7.40+): NEW lcl_capacity_report( )->run( p_carr ) and* REDUCE i( INIT n = 0 FOR f IN flights WHERE ( ... ) NEXT n = n + 1 ).Real project scenario
A 4,000-line report with FORM routines and 80 global variables needed a small change to its capacity calculation. The developer estimated three days, mostly to understand side effects; after the change, an unrelated output section broke because a global variable was reused.
In the next change, the team extracted the calculation into a small method with parameters, added two ABAP Unit tests and introduced constants for thresholds. Subsequent changes to that logic took an hour, and the tests caught a regression before transport.
Common mistakes
- Huge reports with global variables and FORM routines.
- Cryptic names (itab, wa, cnt).
- Magic numbers and codes.
- Mixing database access, logic and output in one block.
- No automated tests or ATC checks.
Best practices
- Follow the Clean ABAP style guide.
- Local classes with small methods even in reports.
- Separate data access, logic and output.
- Constants/enums for fixed values.
- Run ATC and ABAP Unit before every transport.
Interview angle
Questions: "What is Clean ABAP?", "How do you make a report testable?", "Which obsolete statements do you avoid?"
Strong answer: Clean ABAP is SAP's style guide for readable, maintainable code: descriptive names, small methods, classes instead of FORMs, modern syntax, constants, exceptions, testability; make reports testable by moving logic into methods with parameters separated from DB access and output, then cover with ABAP Unit; avoid FORM/PERFORM in new code, header lines, OCCURS, MOVE, TABLES in classes; use ATC.
Practice this lesson
Quick check
1. Which change best improves a report full of FORM routines and global variables?
2. Which Clean ABAP practice makes business logic testable with ABAP Unit?
3. What best characterizes the fundamental difference between a FORM subroutine and a METHOD in ABAP?
Interview questions
1. A pricing enhancement contains hundreds of nested IF statements. How would you refactor it?
Answer it in your own words first, then compare.
2. How would you refactor a 4000-line report into maintainable code?
Answer it in your own words first, then compare.
Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.
More lessons in this topic
- ABAP Core Part 1: Your First ABAP Program and the Development Tools
- ABAP Core Part 2: DATA, TYPES, CONSTANTS, Work Areas and Internal Tables
- ABAP Core Part 3: Data Types and Literals
- ABAP Core Part 4: Control Flow and Building Output Texts
- ABAP Core Part 5: Selection Screens — PARAMETERS, SELECT-OPTIONS and Validation
- ABAP Core Part 6: System Fields — sy-subrc, sy-tabix, sy-datum and More
- ABAP Core Part 7: Operators, Calculations and Type Conversion
- ABAP Core Part 8: Messages and User-Friendly Error Handling