Best Practices – von den Fehlern anderer lernen
Wenn man eine Zeit lang selbst programmiert hat, wird man sich gewisse Standardverhalten aneignen und diese immer wieder anwenden. Man hat gelernt, welche „Tricks“
einem die Arbeit erleichtern. Die meisten dieser Verhaltensmuster hat man sich dadurch angeeignet, weil man viele Fehler gemacht hat und hinterher erst gemerkt hat,
wie es eigentlich besser gewesen wäre. Nun liegt es nahe, sich an den erfahrenen Programmierern zu orientieren und sich deren Verhaltensmuster anzueignen. Das ist erstmal
eine gute Idee – wobei man hier auch nicht alles unkritisch übernehmen sollte. Um ein nicht technisches Beispiel zu bemühen, war es in den 90ern und Anfang der 2000er Jahre üblich,
Softwareprojekte nach dem „Wasserfall Prinzip“ zu entwickeln. Man hat eine Definition der Funktionalität gemacht und wenn alles komplett definiert wurde, begannen die Entwickler
mit ihrer Arbeit. Eine nachträgliche Funktionsänderung war verpönt und hat meist zu langen Diskussionen geführt – vor allem wenn dadurch sich der Zeitplan, oder noch schlimmer der
Kostenrahmen geändert hat. Heutzutage ist es nicht unüblich die Software in einem iterativen Prozess zu entwickeln. Man programmiert erstmal einen kleinen Teil der Software,
bespricht das Ergebnis mit den Auftraggebern und überlegt dann gemeinsam, was die nächsten zu realisierendem Features sind. Beide Methoden haben seine Vor- und Nachteile
und man sollte sich nicht von einem Verfechter der einen oder anderen Lehre überreden lassen, was nun der heilige Gral der Softwareentwicklung ist. Trotzdem sollte man sich
beide Seiten anhören. Insofern biete ich hier lediglich Denkanstöße an, welche einem den Weg zu eigenen sinnvollen Verhaltensweisen weniger steinig gestallten sollen. Da
dies ein Programmierbuch und kein Projektmanagement Buch ist, gehe ich hier aber nicht auf solche Dinge wie Wasserfall vs. Agil ein, sondern „lediglich“ auf einige grundlegende
technischen Fragestellungen.

Modularität
Beginnen wir mit der Übersichtlichkeit. Code sollte immer modular und sinnvoll aufgeteilt werden. Eine Funktion, welche hunderte von Zeilen aufweist ist oftmals nicht mehr zu durchdringen.
Das gilt vor allem für andere Entwickler, welche gegebenenfalls den Code ebenfalls verstehen wollen oder gar müssen. Aber auch für einen selbst. Es kommt nicht selten vor, dass man sich
einen Programmcode ansieht, welchen man vor ein paar Monaten geschrieben hat und sich wundert, was man sich dabei eigentlich gedacht hat. Manche schreiben dann den kompletten Code dieser
Funktion tatsächlich neu. Oftmals liegt dies daran, dass man beim Programmieren gedanklich sehr tief in die Problemstellung eingedrungen ist und sich zu hundert Prozent darauf fokussiert.
Nach einigen Monaten nimmt man sich jedoch die Zeit nicht mehr, diese Gedankengänge neu aufzubauen und versteht die impliziten Zusammenhänge in seinem eigenen Code nicht mehr. Um dieses
Phänomen in den Griff zu bekommen, sollte man sich beim Programmieren immer überlegen, wie ein Außenstehender diesen Code interpretieren würde. Wenn man das Gefühl hat, dass ein Außenstehender
diese Logikansätze nicht nachvollziehen kann, dann muss der Code übersichtlicher gestaltet werden. Hierbei gibt es einige Ansätze.

Namenskonventionen
Zuerst sollten wir Variablen und Funktionen bzw. Methoden übersichtlich benennen. Sehen wir uns hierzu folgenden (zugegebenermaßen sehr vereinfachten) Code an:
Listing 1: Beispielcode für unübersichtliche Programmierung
Wir können zwar die einzelnen Schritte nachvollziehen, es erschließt sich jedoch nicht sofort der Sinn dieser Funktionalität. Wenn wir allerdings den Methodennamen und die Variablennamen sinnvoller
wählen, so wird das Beispiel plötzlich einfacher nachvollziehbarer:
Listing 2: Beispielcode für übersichtliche Programmierung in Java
Plötzlich verstehen wir den Sinn der Methode und können uns ganz anders auf diesen Code einlassen. Es ist nicht immer leicht, die Balance zwischen einem sprechenden und einem kurzen Namen zu
finden – aber hier wird sich mit der Zeit auch Routine breit machen.

Konstanten und Emuns
Der nächste wichtige Punkt ist die Nutzung von Konstanten. Sehen wir uns hierzu folgenden Code an:
Listing 3: Beispielcode für Nutzung von Konstanten in Java
Wir erhalten ein Array mit Polygonpunkten, welche alle mit einem X- und einem Y- Wert bestimmt sind, wodurch wir ein zweidimensionales Array benötigen. Über die Schleife lesen wir alle
Punkte aus und schreiben sie in die Konsole. Der Zugriff auf den X bzw. Y Wert kann nun entweder über den Wert 0 und 1 erfolgen, wodurch wir
"Point (" + point[0] + "/" + point[1] + ")" schreiben müssten. Durch die Definition von Konstanten geben wir aber den Werten 0 und 1 einen sinnvollen Namen, wodurch die Intention des Codes
sehr viel besser zu verstehen ist. Konstanten sind Datenkonstrukte, welche nicht mehr verändert werden können. Wenn ich also versuche, dem X einen neuen Wert zuzuweisen, wird dies zu einem
Fehler führen. Es ist eine allgemein anerkannte Konvention, Konstanten ausschließlich mit Großbuchstaben zu schreiben. Dadurch wird dem Leser des Codes sofort die Eigenschaft der
„nicht mehr Veränderbarkeit“ transparent.
Eine weitere Möglichkeit, Werten einen sinnvollen Namen zu geben sind Aufzählungstypen, oft auch „Enums“ (von Englisch „enumeration“) genannt. Diese nutzt man, wenn eine bestimmte begrenzte Menge
von Werten – oder besser Zuständen – zu verarbeiten ist:
Listing 4: Beispiel für Nutzung von Aufzählungstypen in Java
In vielen Programmiersprachen arbeitet man mit Aufzählungstypen meist in
switch/case Statements oder als Keys in assoziativen Arrays wie bspw.
Hashtable. Es ist aber auch möglich,
enum Datentypen ähnlich wie Objekte mit weiteren Funktionalitäten zu erweitern. Dies ist aber nicht in allen Programmiersprachen möglich.
Was: | Schlüsselwort | Beispiel | |
---|---|---|---|
Java | Konstanten | final | final double PI = 3.14; |
Aufzählung | enum | public enum Wochentag { MO, DI, MI, DO, FR, SA, SO } Wochentag myDay = Wochentag.MO; |
|
C/C++ | Konstanten | const | const double PI = 3.14; |
Aufzählung | enum | enum Wochentag {MO, DI, MI, DO, FR, SA, SO}; enum Wochentag myDay = MO; |
|
C# | Konstanten | const | const double PI = 3.14; |
Aufzählung | enum | pulic enum Wochentag { MO, DI, MI, DO, FR, SA, SO } Wochentag myDay = Wochentag.MO; |
|
JavaScript | Konstanten | const | const PI = 3.14; |
Aufzählung | - | wird nicht unterstützt | |
PHP | Konstanten | define | define {"PI", 3.14); |
Aufzählung | enum | enum Wochentag { case MO; case DI; case MI; case DO; case FR; case SA; case SO; } $myDay = Wochentag::MO; |
|
Python | Konstanten | Großbuchstaben(1) | const double PI = 3.14; |
Aufzählung | Enum / class | from enum import Enum class Wochentag (Enum): MO = 1 DI = 2 MI = 3 DO = 4 FR = 5 SA = 6 SO = 7 myDay = Wochentag.MO |
Tabelle 1: Syntaxregeln für Aufzählungstypen und Konstanten
(1) In Python gibt es keine Konstanten. Per Konvention wird aber über Großbuchstaben signalisiert, dass der Wert nicht geändert werden soll.

Kommentare
Alles, was man nun nicht mit sinnvollen Namensregeln erklären kann, sollte mit Kommentaren versehen werden. Ein Kommentar ist ein Bereich im Code, welcher nicht durch den Prozessor oder dem
Interpreter ausgewertet wird. Die meisten Programmiersprachen orientieren sich an den Kommentarzeichen, wie sie in C verwendet werden. Hierbei gibt es im Wesentlichen zwei unterschiedliche Kommentararten:
- Zeilenkommentar
- Blockkommentar
Listing 5: Beispiel für Zeilen- und Blockkommentar
Üblicherweise nutzt man innerhalb des Codes meist Zeilenkommentare. Der Hintergrund ist, dass man mitunter beim Testen temporär Codebereiche „auskommentieren“ möchte – sie also
inaktiv setzt. Dies macht man meist mit Blockkommentaren, da die Zeilenkommentare damit nicht interferieren. Wenn ich also die Schleife im oberen Code auskommentieren möchte, kann ich dies wie folgt tun:
Listing 6: Beispiel für das Auskommentieren von Code
Damit würde der Code lediglich noch die Ausgabe „Fertig!“ durchführen – alles andere ist inaktiv. Wenn ich aber den gesamten Code auskommentieren möchte, so gibt es einen Fehler:
Listing 7: Fehlerhaftes Beispiel für das Auskommentieren von Code
Hier wird der auskommentierte Bereich durch den bereits vorher existenten Blockkommentar beendet. Der Compiler sieht also in der Zeile nach der Ausgabe von „Fertig!“
scheinbar das Ende eines Blockkommentars ohne einen zugehörigen öffnenden Marker.
Diese Art von Kommentar wird für alle hier beschriebenen Sprachen genutzt, außer Python. Hier existiert lediglich der Zeilenkommentar, der mit einem Hashtag (#) eingeleitet wird.
Neben dem Block- und Zeilenkommentar gibt es noch weitere „Feinheiten“ beim Erstellen von Kommentaren. Vor allem Java bedient sich hier einer erweiterten Form von Blockkommentaren,
welche von einem Tool namens „Javadoc“ ausgewertet wird. Hierbei geht dieses Tool durch den gesamten Code und erzeugt basierend auf dem erweiterten Kommentarsyntax eine HTML Dokumentation
des Codes. Hier ein Beispiel für eine Methode, welche mit Javadoc kompatiblen Kommentaren versehen wurde:
Listing 8: Integriertes Dokumentationsverfahren in Java
Der Dokumentationsblock wird mit /** eingeleitet und erlaubt auch HTML Tags für die Textformatierung. Aus dem Kommentar wird dann mittels Javadoc folgende HTML Seite erstellt:

Abb.: 1: JavaDoc Ergebnis des vorausgegangenen Kommentarblocks.
Die anderen Programmiersprachen nutzen hier oftmals externe Tools, welche wiederum eigene Regeln definiert haben. Hier ist es sinnvoll sich vor einem Projekt über die Möglichkeiten zu informieren.

Pattern
Zum Schluss noch ein Hinweis zum architektonischen Vorgehen. Bei der Programmierung ist es üblich, sich vorab nach geeigneten Entwurfsmuster (engl. „design pattern“) zu informieren. Ein solches Entwurfsmuster
ist eine Art Vorlage, wie man gewisse Softwareansätze architektonisch sinnvoll aufsetzt. Es gibt eine große Zahl an solchen Entwurfsmustern, welche sich auf teilweise sehr spezifische Themen konzentrieren.
Andere wiederum sind so breit akzeptiert, dass sie als quasi Standard bei der Softwareentwicklung eingesetzt werden. Hierzu würde beispielsweise das MVC (Model View Control) Pattern zählen, welches die
Trennung einer Businesslogik (Model) von dem Userinterface (View) und der Komponente für die Nachrichtensteuerung (Control) vorschlägt. Für den Programmieranfänger ist es mit Sicherheit nicht der erste
Schritt, sich mit solchen Pattern zu beschäftigen. Bei größeren Projekten empfehle ich aber, sich mit diesen Strukturen vorab auseinanderzusetzen, damit der einmal gewählte Ansatz möglichst bis zum
Abschluss des Projektes die Umsetzung vereinfacht und langfristig die Wartung erleichtert.

CC Lizenz (BY NC SA)