Die S/4HANA-Umstellungen, die bei vielen Firmen auf Hochtouren laufen bringen es besonders deutlich zu Tage, wenn Programme hinsichtlich Wartbarkeit schlecht programmiert wurden.In diesem Artikel möchte ich versuchen, Ihnen die Wichtigkeit von Wartbarkeit im SAP-Umfeld näher zu bringen.
Definition
Beginnen wir, wie so häufig in Fachartikeln, mit der Definition. Wikipedia äußert sich zu Wartbarkeit wie folgt:
Die Wartbarkeit (englisch maintainability, supportability oder serviceability) von Software ist die Einfachheit, mit der ein Softwaresystem oder eine Softwarekomponente modifiziert werden kann, um Fehler zu beheben, Performanz oder andere Attribute zu verbessern oder Anpassungen an die veränderte Umgebung vorzunehmen.
Das ist sehr allgemein und abstrakt.
Wikipedia bringt es im nächsten Absatz jedoch bereits sehr gut auf den Punkt:
Wartbarkeit ist umso wichtiger
- je größer die geplante Verwendungsdauer der Software ist
- je geringer die Verfügbarkeit von Experten für das Sachgebiet ist
Bei SAP-Programmen haben wir eine sehr lange Verwendungsdauer und zusätzlich sind Experten häufig rar, da bei der SAP-Programmierung nicht nur technisches Wissen gefragt ist, sondern oftmals auch Modulwissen wichtig ist. Entwickler sind also nicht beliebig austauschbar. Aus diesem Grund ist es unerlässlich, dass Programme hinsichtlich Wartbarkeit auf einem hohen Niveau erstellt werden.
Schlüsselaspekte
Folgende Aspekte gelten generell, wenn es um Quelltext geht. Im Kapitel „Wartbarkeit unter SAP-Gesichtspunkten“ werde ich darauf eingehen, was dies speziell im SAP-Kontext bedeutet.
- Lesbarkeit des Codes: Der Code sollte klar und verständlich sein, damit Entwickler ihn leicht nachvollziehen können. Gut benannte Variablen, Funktionen und Klassen sowie ein konsistenter Stil helfen dabei.
- Modularität: Die Applikation sollte in unabhängige Komponenten unterteilt sein, die getrennt voneinander entwickelt, getestet und gewartet werden können. Dies erleichtert es, Änderungen vorzunehmen, ohne das gesamte System zu beeinflussen.
- Dokumentation: Eine gute Dokumentation, die den Code und seine Struktur beschreibt, ist entscheidend. Dies umfasst sowohl Inline-Kommentare als auch externe Dokumente, die den Zweck und die Funktionsweise erläutern.
- Tests: Umfangreiche Tests, einschließlich Unit-Tests, Integrationstests und Systemtests, sind wichtig, um sicherzustellen, dass Änderungen am Code nicht zu unbeabsichtigten Fehlern führen.
- Flexibilität und Erweiterbarkeit: Der Code sollte so geschrieben sein, dass er leicht erweiterbar ist. Dies bedeutet, dass neue Funktionen oder Änderungen einfach hinzugefügt werden können, ohne bestehende Funktionalitäten zu beeinträchtigen.
- Fehlerbehandlung und Logging: Eine robuste Fehlerbehandlung und aussagekräftige Logging-Mechanismen erleichtern das Debuggen und die Identifizierung von Problemen im System.
Wartbarkeit unter SAP-Gesichtspunkten
In diesem Kapitel werde ich auf spezielle Herausforderungen eingehen, die meinen Kolleginnen und Kollegen und mir häufig begegnen. Ich versuche aufzuzeigen, welche Hilfsmittel es gibt und wie besonders gravierende Fehler vermieden werden können.
Lesbarkeit des Codes
Bei der Lesbarkeit des Codes gehen die Meinungen häufig sehr auseinander. Angefangen mit der Diskussion, ob die ungarische Notation verwendet werden soll oder nicht. Es gibt keinen einheitlichen Standard für „Lesbarkeit“, denn was für den einen klar und verständlich ist, wirft für einen anderen Fragen auf. Es gibt immer noch Firmen, bei denen Objektorientierte Programmierung unerwünscht ist, da die Firmeneigenen Entwickelnden nicht genug Expertise mit dieser Methode haben. Auch an die neuen ABAP Features muss man sich erst gewöhnen.
Abbildung 1 Moderner ABAP-Quelltext zur Konvertierung einer Tabelle in eine andere
Auch das Einrücken von Code dient der Lesbarkeit. Aber auch hier gehen die Meinungen auseinander, wann etwas besser oder schlechter lesbar ist. Hinzu kommt, dass den einen bestimmte Dinge stören, den anderen gar nicht. Ich persönlich bekomme fast körperliche Schmerzen, wenn Quelltext nicht einheitlich ordentlich eingerückt ist.
Seit etwa 2020 gibt es den offiziellen SAP Style Guide, der viele Fragen klärt. Zusammen mit den Open Source Projekten ABAPlint und ABAP Cleaner gibt es jedoch inzwischen gute Möglichkeiten, einheitlichen Code zu erzeugen. Mit dem ABAP Cleaner kann der gesamte Quelltext auf Knopfdruck formatiert werden. Die Möglichkeiten gehen weit über die des Pretty Printers hinaus. Die Konfigurationsmöglichkeiten sind vielfältig und auf eigene Wünsche einstellbar.
Die technischen Möglichkeiten nach allgemein anerkannten Regeln der Codeformatierungen durchzuführen sind also inzwischen vorhanden und einfach anwendbar. Aber was hat die Firma denn nun für Vorteile, wenn Code einheitlich und lesbar formatiert ist?
Es gibt die Annahme, dass Quelltext etwa zehnmal öfter gelesen als geschrieben wird. Meiner Meinung nach ist die Relation deutlich größer, denn beim Programmieren selbst lese ich den Quelltext etliche Male und mache eventuell nur geringe Änderungen. Worauf ich hinaus will, ist, dass lesbarer Code sowohl die Analyse als auch das Programmieren einfacher macht. Wenn Fehler auftreten, dann möchte ich schnell und eindeutig erkennen können, was im Quellcode passiert. Denn wenn ich gut verstehen kann, was im Coding passiert, dann kann ich in der Regel auch entsprechend handeln. Wenn es jedoch unklar ist, dann verzögert es das Verständnis und die Fehlerkorrektur.
Ein wichtiger Bestandteil von lesbarem Code ist die Verwendung von sprechenden und treffenden Namen für die einzelnen Objekte (Klassen, Methoden, Variablen, …). Leider gibt es im SAP-System eine Einschränkung, die die Namenslänge auf 30 Zeichen begrenzt. In der Regel reicht diese Länge aus. Manchmal wäre es jedoch hilfreich, wenn längere Methodennamen verwendet werden könnten.
Jedoch scheiden sich auch hier die Geister. Wenn ich eine interne Tabelle mit Namen RETURNED_FAULTY_EQUIPMENTS habe, dann ist der Name einerseits sprechend, andererseits muss ich diesen Text auch immer lesen bzw. schreiben. Sollte ein Zugriff auf diese Tabelle öfter vorkommen, könnte es von Vorteil sein, die Tabelle nur EQUIS zu nennen und bei der Datendeklaration zu dokumentieren, welche Equipments in der Tabelle vorhanden sind.
Das folgende Beispiel soll verdeutlichen, auf was ich hinaus möchte. Der folgende Quelltext ist „sprechend“:
Das hier aufgeführte Beispiel ist eher „technisch“:
Entscheiden Sie selbst, welches besser lesbar ist und wie wichtig dieser Aspekt unter einzelnen Gesichtspunkten ist.
Modularität
Robert C. Martin, einer der bekanntesten Verfechter von Clean Code, empfiehlt eine Anzahl von maximal 20 Zeilen Code je Methode. Im SAP-Umfeld ist das nur selten einzuhalten. Allein der Aufruf eines BAPIs benötigt inklusive der Datendeklaration häufig bereits 40 Zeilen und mehr. Man sollte darauf achten, dass eine Programmeinheit nur so viel Coding wie nötig enthalten sollte. Bei SAP-Programmen ist dies häufig nicht der Fall und Einheiten von 1000 Zeilen Coding sind keine Seltenheit. SAP selbst ist hier leider auch kein gutes Vorbild.
Die Modularisierung ist ein wichtiger Bestandteil, um Programme lesbarer zu machen. Die Objektorientierung hilft hierbei, denn sie ermöglicht eine kurze Schreibweise und die direkte Zuweisung eines Wertes durch Verwendung des RETURNING-Parameters.
Besonders beim Debuggen von Programmcode ist es hilfreich, wenn bereits am Namen ersichtlich ist, was ein Modul macht. In dem folgenden Beispiel ist klar ersichtlich, was passiert:
Die einzelnen Module können separat geändert und getestet werden. Das macht es lesbar und robust gegen Änderungen.
Ein weiterer wichtiger Aspekt bei der Modularisierung ist die Trennung von Datenbeschaffung, Geschäftslogik und Oberfläche.
Dokumentation
Ein ewiges Streitthema sind Dokumentationen. Wie viel Dokumentation ist notwendig? Was muss dokumentiert werden und wo wird die Dokumentation abgelegt?
Jedes Objekt (Programm, Klasse, Tabelle, Datenelement etc.) kann im SAP dokumentiert werden. Allerdings ist es sehr mühsam, da die Integration des Word-Editors oftmals nicht reibungslos funktioniert. Zudem ist es nicht möglich, Screenshots oder andere erklärende Bilder einzubinden. Auch Links können nicht ohne Weiteres verwendet werden. Der Vorteil ist jedoch, dass sich die Dokumentation direkt am Objekt im SAP-System befindet und daher direkt zugänglich ist.
Die Verwendung von externen Programmen, wie zum Beispiel Word oder Visio, stellen eine deutlich bessere Möglichkeit der Dokumentation dar. Allerdings muss diese Dokumentation auch auffindbar sein.
Die Inline-Dokumentation, also die Nutzung von Kommentaren direkt im Quelltext ist auf jeden Fall unerlässlich. Es gibt zwar Stimmen, die behaupten, dass guter Quelltext keine Dokumentation benötigt, aber da bin ich anderer Meinung. Sinnvolle Kommentare sind hilfreich für das Verständnis eines Programms.
Tests
Unit Tests sind in der SAP-Welt immer noch eher eine Seltenheit. Meiner Meinung nach liegt es daran, dass viel SAP-eigene Funktionen verwendet werden und fast immer Datenbankzugriffe im Spiel sind. Die Trennung von Datenselektion, Geschäftslogik und Oberfläche ist aufwändig. Häufig lohnt sich dieser Aufwand jedoch nicht, wenn „nur ein paar Daten selektiert“ werden sollen, „ein bisschen gerechnet“ wird und dann die Ausgabe im ALV-Grid erfolgt. Das ist aus meiner Sicht auch legitim. Wenn dieses Programm jedoch immer wieder erweitert wird, dann sollte man den richtigen Zeitpunkt nicht verpassen, die Programmarchitektur zwecks Wartbarkeit anzupassen.
Jeder muss selbst erfahren und sich erarbeiten, wann es sinnvoll ist, Unit Tests einzusetzen. Mit diesem Wissen im Hinterkopf ergibt sich bereits eine komplett andere Programmarchitektur.
Die Erstellung von Unit Tests ist zusätzlich eine Möglichkeit der Dokumentation. Ein Entwickler kann sehen, welche Konstellationen möglich sind. Wird ein Fehler korrigiert, kann man anhand der erstellten Testfälle erkennen, ob diese nach wie vor das gleiche Ergebnis liefern.
Auch statische Programmprüfungen können helfen, ein Programm robust und wartbar zu machen. Im SAP stehen dafür der Code-Inspector und die ATC-Prüfungen zur Verfügung. Diese Tools helfen dabei Probleme zu vermeiden, bevor sie entstehen. Beide Hilfsmittel können individuell eingestellt werden. Die einfachste Prüfung ist zugleich die, die Entwicklern am wenigsten Spaß macht: Die Prüfung, ob nach bestimmten Programmeinheiten, wie zum Beispiel Funktionsbausteinaufrufen oder Datenbankoperationen, der Returncode abgefragt wird.
Flexibilität und Erweiterbarkeit
Wenn die oben genannten Punkte bereits berücksichtigt wurden, besteht eine gute Chance, dass der Code flexibel einsetzbar ist und leicht erweitert werden kann. Eine gute Lesbarkeit führt zu einem guten Verständnis der Programmlogik. Die Modularisierung führt ebenfalls dazu, dass der Quelltext leicht angepasst werden kann. Sollte sich die Logik von SET_SENDER aus dem oben genannten Beispiel ändern, dann kann die Methode leicht getauscht werden. Ebenso kann eine neue Funktion, wie zum Beispiel ADD_DOCUMENT, eingefügt werden.
Wird bei der Entwicklung mit INTERFACES gearbeitet, können ganze Klassen durch eine neue Funktionalität ersetzt werden.
Fehlerbehandlung und Logging
Viele Programmierer gehen bei der Programmierung und beim Testen nach dem Happy Path vor. Die Testdaten werden so gewählt, dass alle geforderten Programmbestandteile durchlaufen werden. Schließlich möchte man sichergehen, dass alle Funktionen das machen, was sie sollen. Hierbei wird oftmals übersehen, dass an verschiedenen Stellen Probleme auftreten können. Eine konsequente Fehlerbehandlung ist deswegen hilfreich.
Im schlechtesten Fall erhält ein Benutzer beim Auftreten eines Fehlers die Meldung „Es ist ein Fehler aufgetreten“ oder gar einen Short Dump. Sollte an dieser Stelle häufiger ein Fehler auftreten, muss die Fehlerbehandlung ausführlicher erfolgen. Wenn ein Fehlerfall wahrscheinlich ist (das zu bearbeitende Objekt ist durch einen anderen Benutzer gesperrt), dann muss eine erklärende Meldung mit allen notwendigen Informationen ausgegeben werden.
Das Schreiben von Daten zur Fehlerermittlung oder Protokollierung von Aktivitäten ist ebenfalls ein wichtiger Bestandteil bei wartbaren Programmen. Im SAP-System wird hierfür in der Regel das Business-Application-Log (BAL) verwendet. Mit dieser Applikation können Daten standardisiert in ein Log geschrieben und bei Bedarf auf der Datenbank gesichert werden. Für die Protokollierung von Programmabläufen können Log-Points verwendet werden. Diese werden im Programmcode gesetzt und über die Transaktion SAAB bei Bedarf aktiviert. Es können sogar dynamische Log-Points gesetzt werden. Diese müssen nicht im Programm aufgerufen, sondern können im Debugging gesetzt und aktiviert werden.
Hinderungsgründe für wartbare Programme
Die Wartbarkeit eines Programms hängt von vielen Dingen ab. Einige habe ich oben aufgezeigt. Was genau Wartbarkeit heißt, kann jedoch von Fall zu Fall und je nach Sichtweise anders sein. Je nach Anwendungsfall müssen einzelne Aspekte stärker betrachtet werden als andere. Bei einer Anwendung, die täglich von vielen Benutzern und Benutzerinnen ausgeführt und häufig erweitert wird, sollte man in besonderem Maße auf Wartbarkeit achten.
Wenn das alles so wichtig ist, warum wird bei der Erstellung von Programmen oder der Änderung nicht genug auf Wartbarkeit geachtet?
Bei der Erstellung einer Applikation ist das Wichtigste, dass das Programm funktioniert und den Anforderungen entspricht. Sobald es funktioniert, möchte ein Entwickler jedoch keine Änderungen mehr machen, da das die soeben erstellte Funktionalität wieder zerstören könnte. Zudem ist der kurzfristige Erfolg häufig wichtiger als die langfristige Wartbarkeit.
Fairerweise muss ich sagen, dass es zwar Techniken gibt, um potenziell wartbaren Quelltext zu erstellen, allerdings stellt sich oft erst später heraus, welche Wartbarkeitsaspekte sich im Laufe der Zeit als wichtig herausstellen.
Ein weiterer Aspekt, der gegen die Wartbarkeit spricht, ist Zeitdruck. Gerade Fehlerbehebungen werden in der Regel unter großem Stress und Termindruck ausgeführt. In dieser Situation ist keine Zeit für das Refrakturieren von Code und dem Schreiben von Unit Tests. Auch wenn das kurzfristig gedacht ist, sobald der Fehler behoben wurde, besteht das Problem nicht mehr und die Wartbarkeit ist aus dem Sinn. Dazu kommt, dass nicht erfasst wird, wie lange an einem Problem gearbeitet wurde. Täte man dies, dann könnte man erkennen, dass die Fehlerbehebung an bestimmten Programmen länger dauert. Hier könnten die Gründe ermittelt und mit entsprechenden Codeverbesserungen entgegengewirkt werden.
Fazit
Es gibt keinen Standard und keine einheitliche Vorgehensweise, um wartbare Applikationen zu schreiben. Das sollte Entwickelnde jedoch nicht daran hindern, nach bestem Wissen und Gewissen diesem Ziel entgegenzuarbeiten. Erfahrung ist sehr wichtig. Viele Dinge lassen sich jedoch einfach umsetzen und fordern eher den inneren Schweinehund heraus. Ich habe etliche Programme gesehen, bei denen sich die Ersteller nicht einmal die Mühe gemacht haben, überflüssige Kommentare zu löschen oder den Pretty Printer aufzurufen.
Auch bei der Programmierung finde ich den alten Pfadfinderspruch gut, den Lord Robert Baden-Powell, der Begründer der Pfadfinderbewegung geprägt hat:
Versucht, die Welt ein bisschen besser zurückzulassen, als Ihr sie vorgefunden habt.