Aus dem Blog

Golo & Götz (12)

von Götz Martinek

Standard oder Eigenbau bei altem Code

"Golo & Götz ist eine gemeinsame Serie von Golo Roden und Götz Martinek. Der eine ist CTO der the native web GmbH, der andere Geschäftsführer der sodge IT GmbH. Was die beiden vereint, ist ihre große Leidenschaft für die Entwicklung von Software. Seit September 2019 nehmen sie sich monatlich ein Thema vor, zu dem dann jeder seine individuelle Perspektive beschreibt, ohne den Artikel des jeweils anderen im Vorfeld zu kennen. Der zugehörige Artikel von Golo findet sich in seinem Blog auf heise.de/developer.

Die Fragestellung zu diesem Beitrag lautete: "Standard oder Eigenbau bei altem Code"

Standard oder Eigenbau bei altem Code

Wenn man in einem bestehenden Projekt weiterentwickeln soll, kommt man früher oder später an den Punkt, an dem man sozusagen auf den "Train of Logic" des oder der ursprünglichen Entwickler aufspringen sollte. Und wie früher bei alten Adventurespielen ist das mehr oder weniger einfach, den Gedanken des ursprünglichen Authors zu folgen.

Man sieht vieles bei bestehendem Code, je nach Alter des Projektes kann man stellenweise auch Paradigmenänderungen über der Zeit finden. Es ist ein wenig wie "Source-Archäologie". Manche Stellen sind oder waren einmal Standard, manchmal sind es Passagen, die in ähnlicher Form heute als Standard zu finden sind. Andere sind völlig kreative Eigenentwicklungen, deren Lösungsansatz (heute) völlig "verwirrt" wirkt und (heute) mit einem Standardpattern gelöst wird. Da aber zum Entstehungszeitpunkt des Codes vermutlich kein solcher Standard bekannt war, musste man sich eben anders helfen.

Wenn man nun eine Stelle gefunden hat, die man am liebsten reflexartig umbauen würde? Ist es sinnvoll diesem Reflex zu folgen?
Man will es ja schließlich verbessern, also warum denn nicht?!?

Bevor man dem Reflex erliegt, sollte man einen Schritt zurück gehen und sich folgende Punkte vor Augen führen. Um so über seine geplante Änderung zu sinnieren, da jede Änderungen positives, negatives, Gefahren und mögliche langfristige Auswirkungen haben kann.

Ist der zu ändernde Code durch Tests abgedeckt?
Eine der wichtigsten Fragen ist, ob es zum zu ändernden Code Tests gibt. Beziehungsweise, ob es überhaupt eine halbwegs gute Testabdeckung im gesamten Projekt gibt. Nur wenn die Testabdeckung vorhanden ist, macht es Sinn, sich auf Änderungen am Code einzulassen. Andernfalls läuft man Gefahr, dass durch Codeänderungen eine Kettenreaktion an Fehlern ausgelöst wird. Diese treten dann meist an völlig unerwarteten Stellen auf. Im Zweifel auch neue Tests schreiben, ohne das Grundverhalten geändert zu haben. Das hilft bei kommenden Änderungen.

Passt das Alte zum Rest?
Passt der bestehende Code zum Rest des Projektes. Wenn es aus einem Guss wirkt, sollte man sich noch die anderen Stellen anschauen, die so ähnlich aussehen, ggf. sind hier noch Referenzen zu finden. Gerade bei Problemen, die auf ein und die selbe Art gelöst werden, kann es vorkommen, dass "abgekürzt" wird.

Passt das Neue zum Rest?
Wenn man den neuen Code integriert, wirkt er für spätere Entwickler dann völlig aufgesetzt? Dann sollte man sich Gedanken machen, welche Teile des Codes noch zu ändern wären. Der neue Code sollte nicht wie ein Alien auftreten. Einige ausführliche Kommentare können hier schon helfen.

Ist es für neue Entwickler komplizierter als vorher?
Sollte der neue Code zwar kürzer, ggf. auch "schöner" sein, aber sehr schwer lesbar, dann sollte man sich überlegen, wie oft ein späterer Entwickler damit direkt zu tun hat. Nur wenn dieser in Zukunft sehr wahrscheinlich nicht in den Internas des neuen Codes arbeiten muss, sollte man sich auf so etwas einlassen. Ganz schlimm sind Fälle, in denen dann bei diesem schwer verständlichen Code Fehler auftreten, die ein anderer Entwickler fixen muss.

Ist es nur die Hälfte der Wahrheit?
Ist die von uns angedachte Codeänderung vielleicht nur teilweise richtig? Wird das, was wir ändern wollen, ggf. an einer völlig anderen Stelle "kreativ" genutzt? Würden wir diesen "kreativen" Einsatz ggf. zerstören? Da uns hier die IDE mitunter nicht immer helfen kann, sind solche Punkte meist schwer zu entdecken. Oft werden sie erst, nachdem man die Änderung durchgeführt hat, entdeckt, im Idealfall als Compilefehler, im dümmsten Fall durch den Kunden als Runtimefehler.

Führt es eine weitere Lösung zu einem Problem ein?
Führen wir mit unserem neuen Code eine weitere Lösung ein? D.h., gibt es im Code Stellen, die ähnlich zu der sind, die wir einbauen wollen? Wenn das der Fall ist, würde das spätere Entwickler wieder verwirren, da es zwei Wege zum Ziel gibt. Hier sollte man sich die zweite Variante auch anschauen und ggf. vereinheitlichen.

Würde eine bessere Benennung schon helfen?
Oft reicht es auch schon, Namen zu ändern, das löst zwar kein direktes Feature- oder Bugproblem. Hilft aber oft bei der Verständlichkeit des Codes. Kleine Änderungen können auch helfen. Frei nach CleanCode und der Pfadfinderregel "Verlasse den Code sauberer als du ihn vorgefunden hast".

Ist das alte ein Standardlösungsansatz?
Sollte der alte Code eine (ehemals) Standardlösung sein, sollte man nochmal drüber nachdenken, warum man diesen Code anfassen will. Von (altem) Standard zu (neuem) Standard klingt gut, hat aber oft einen enormen Rattenschwanz. Von (altem) Standard zu Eigenentwicklung nur im Notfall. Dies führt früher oder später wieder zu einer Betrachtung des neu eingebauten Codes nach diesen Punkten.

Was genau würde die geplante Änderung fixen?
Zukünftige Leichtsinnsfehler? Hierbei sollte man sich auch überlegen, ob so ein Fehler zur Compiletime oder Runtime auftritt. Ein Compiletimefehler ist durchaus zumutbar, aber letztere gilt es zu vermeiden. Also lieber nur anfassen, wenn wirklich nötig.

Alter Code hat Erfahrung!
Was man auf keinen Fall vergessen sollte, alter Code ist nicht einfach schlecht, weil er alt ist. Alter Code hat Erfahrung. Code, der schon Jahre lang im Einsatz ist, hat viele Usecases "überlebt". Womöglich Usecases, von denen spätere Entwickler noch nicht mal etwas gehört haben. Was wiederum heißt, eine Änderung des Codes, der diese unbekannten UseCases mit abdeckt, wäre nichts weiter als Zufall. Also bitte nicht einfach nur ändern, weil es heute anders geht.


Mindestens diese Dinge gilt es zu beachten und zu bewerten. Schnelles ändern von Stellen im Code führt langfristig meist zu Situationen wie diesen https://www.youtube.com/watch?v=mGGp_2gc5PY . Was dann früher oder später in einer Neuentwicklung endet.

Die Grundidee zur Änderung des Codes sollte sein, einen (heutigen) Standardweg zu wählen, wenn die Änderung sinnvoll und machbar erscheint. Das hat den Vorteil, dass spätere Entwickler diesen Weg erkennen werden und somit schneller verstehen. Komplexe Eigenentwicklungen sind mit Vorsicht zu einzusetzen, da sie früher oder später als "unerwartet" empfunden werden

... und "Unerwartetes" mögen wir nicht ;)

Zurück