"Immer so programmieren, als ob der Maintainer ein gewaltbereiter Psychopath ist, der weiß, wo Du wohnst" - Unter Entwicklern ist das ein gängiger Grundsatz, den besonders diejenigen mit mehr Berufserfahrung verinnerlicht haben. Nur - wie geht das eigentlich?
Die Antwort auf diese Frage soll dieser Artikel liefern und basiert auf meinen eigenen Erfahrungswerten, beziehungsweise den Lektionen, die ich im Laufe der Jahre gelernt habe sowie dem Code, für den ich mich nachträglich geschämt habe.
1. Wert aufs Detail legen
Niemand mag spitzfindige Pedanten, aber gute Senior Developer müssen manchmal riskieren, so wahrgenommen zu werden - wenn sie sicherstellen wollen, dass ihre Codebasis konsistent ist. Das erfordert in erster Linie, klare, verständliche und sinnvolle Regeln aufzustellen und sich anschließend an diese zu halten. Ohne Ausnahme. Dabei gehört es zum guten Ton, sklavisch genau auf die korrekte Einrückung zu achten sowie Linter und Formatter zu nutzen. Penibel auf Groß- und Kleinschreibung von Variablen zu achten oder geschweifte Klammern zu nutzen - selbst wenn das für die gewählte Sprache nicht relevant ist - zeichnet erfahrene Entwickler mit Auge fürs Detail ebenfalls aus.
Das gedankliche Konzept dahinter ist schlüssig: Wer sich um die kleinen Dinge kümmert, muss sich oft gar nicht erst mit großen Dingen herumschlagen.
2. Richtig benennen
Ein etwas angestaubter Entwicklerwitz: "Es gibt zwei schwierige Dinge in der Softwareentwicklung: Cache-Invalidierung, Dinge zu benennen und Off-by-One-Fehler."
Als Entwickler Dinge (sinnvoll) zu benennen, ist tatsächlich nicht immer einfach. An dieser Stelle hilft es, sich Gedanken darüber zu machen, wie schlechte Benennungen zu vermeiden sind. Dabei sollten Sie vor allem folgende Überlegung mit einbeziehen: Der Versuch, ein paar Tastenanschläge sparen zu wollen, ist kein Grund, Variablennamen kryptisch abzukürzen. Das ist ein Relikt der Vergangenheit, in der Terminalfenster noch 80 Zeichen breit waren. Lassen Sie das also und schreiben Sie grossWeight
statt nur gw
und netWeight
statt nw
.
Davon abgesehen, gilt es auch darauf zu achten, die Dinge so vollständig wie möglich zu benennen. Warum sollte man eine Variable "length" nennen, wenn Sie sich auch deutlich präziser als lengthInCentimeters
definieren lässt? Ein langer, dafür aber klarer Variablenname, der den Zweck exakt auf den Punkt bringt, hat absolut keine Nachteile.
3. Erklärende Variablen nutzen
Unerfahrene Programmierer suchen oft nach Abkürzungen - und merken unter Umständen nicht einmal, dass sie das tun. Das führt zu Ergebnissen wie diesem:
function checkAccess(userRole: string, isAuthenticated: boolean, isAdmin: boolean, hasSubscription: boolean, isGuest: boolean): string {
return ((isAuthenticated && userRole === "member") ||
(isAdmin && !hasSubscription) ||
(isGuest && !isAuthenticated && userRole === "guest") ||
(isAuthenticated && userRole === "premium" && hasSubscription))
}
Ich weiß ja nicht, wie es Ihnen geht, aber in meinem Gehirn entstehen Probleme, wenn es mehr als zwei Booleans im Blick behalten muss. Der bessere Weg: Gehen Sie die Dinge Schritt für Schritt an und versehen Sie jede Boolean Expression mit einem Namen, fügen Sie sie zu einem einzigen Wert zusammen und verwenden diesen innerhalb des if
-Statements:
function checkAccess(userRole: string, isAuthenticated: boolean, isAdmin: boolean, hasSubscription: boolean, isGuest: boolean): string {
const isMemberAndAuthenticated = isAuthenticated && userRole === "member";
const isAdminWithoutSubscription = isAdmin && !hasSubscription;
const isGuestAndNotAuthenticated = isGuest && !isAuthenticated && userRole === "guest";
const isPremiumMemberWithSubscription = isAuthenticated && userRole === "premium" && hasSubscription;
const hasAccess = isMemberAndAuthenticated ||
isAdminWithoutSubscription ||
isGuestAndNotAuthenticated ||
isPremiumMemberWithSubscription;
return hasAccess;
}
Diese erklärenden Variablen machen den gesamten Booleschen Ausdruck leicht nachvollziehbar. Darüber hinaus gewährleisten erklärende Variablen auch eine bessere Übersicht im Debugger.
4. Abstraktionen vorziehen
Guten Code zu schreiben, heißt Funktionalität zu schaffen. Gute Senior Devs wissen, dass die Art und Weise, wie etwas gemacht wird, immer optimiert werden kann. Aus diesem Grund ziehen sie Abstraktionen einer konkreten Implementierung vor. Der Gedanke dahinter: Jederzeit könnte eine radikal neue Implementierung auftauchen - die man sich dann nur noch schwierig zunutzemachen kann.
Anders sieht es aus, wenn Sie ein Interface definieren und dagegen coden - neue Implementierungen lassen sich dann im Handumdrehen einbeziehen.
5. Schrittweise testen
Ein gängiger Fehler, den jeder Programmierer macht: Mehr als eine Änderung vornehmen und anschließend den neuen Code testen. Das gewährleistet nur, dass Sie keine Sicherheit darüber haben, welche Änderung nun für ein eventuell auftretendes Problem ursächlich ist.
Erfahrene Entwickler nehmen methodisch eine Änderung nach der anderen vor und sehen sich deren Auswirkungen an, bevor sie fortfahren. Das ist insbesondere bei größeren Code-Basen mit umfangreichen Abhängigkeiten essenziell. Hier kann eine Änderung zu Kaskadeneffekten führen und maximalem Chaos.
6. Chaos unterbinden
Erfahrene Entwickler schreiben niemals einfach Code, um Dinge an random zu bewerkstelligen. Konfigurationseinstellungen sollten beispielsweise ausschließlich an einem Ort gelesen und geschrieben werden. Schließlich schreiben Sie Code für einen Kunden auch nicht einfach an Ort und Stelle, sondern verwenden dazu den Code des Kundenobjekts.
Im Umkehrschluß bedeutet das: Falls Sie das Verhalten eines beliebigen Teils Ihrer Anwendung ändern müssen, sollte es dafür nur eine relevante Stelle geben. Ist hingegen dieselbe Aktion an drei verschiedenen Stellen nötig, kostet das nicht nur Zeit, sondern schafft auch neue Gelegenheiten für Fehler.
7. Sich kurz fassen
Ausufernde Klassen und Methoden sind mit Blick auf die Code-Qualität ein absolutes Gräuel. Eine gute Regel, die sich für mich bewährt hat: Nie mehr als drei Code-Collapse-Zeilen schreiben. Eine andere Empfehlung lautet, dass ein Refactoring ansteht, wenn eine Methode nicht in ihrer Gesamtheit in den Editor passt.
Tief verschachtelter Code entsteht in erster Linie aufgrund zahlreicher, verschachtelter if
-Statements. Wenn Sie diese jedoch invertieren, um auszusteigen, sobald etwas nicht stimmt, können Sie diverse Situationen vermeiden, die die Gehirnwindungen zum Schmelzen bringen. In vielen Fällen können durch die Inversion sämtliche Verschachtelungsebenen in einer Methode entfernt werden. Eine andere Strategie: Extrahieren Sie Code immer in kleinere Methoden, so dass die Blöcke nicht zu groß werden.
8. Nicht kommentieren
Bei diesem letzten Punkten dürften einige Entwickler aus der Fassung geraten. Ich bin trotzdem der festen Überzeugung, dass 99,9 Prozent aller Code-Kommentare ein Anzeichen für schlechten Code, unzureichende Benennungen oder nicht-erklärende Variablen sind. Anders ausgedrückt: Wenn Sie das Bedürfnis haben, Ihren Code zu kommentieren, dann liegt das wahrscheinlich daran, dass der weder klar noch verständlich ist. Dazu kommt außerdem, dass Kommentare nicht physisch an den Code gebunden sind. Sie können also verlorengehen, was zu maximaler Verwirrung führen kann.
Natürlich gibt es auch einige (wenige) Fälle, in denen es sinnvoll ist, Code zu kommentieren. Etwa, wenn der Code für einen ungewöhnlichen Algorithmus optimiert wurde. (fm)
Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten - direkt in Ihre Inbox!