© Danielala/Shutterstock.com
Die Legacy-Code-Falle

Da müssen wir später noch mal ran …


Neben den vielen großen und langjährigen Legacy-Code-Applikationen gibt es immer mehr Neuentwicklungen. Neue Extensions und Module bieten neue Möglichkeiten und somit Chancen für Kunden und Unternehmen. Allerdings gibt es ein großes Problem, das weiterhin Legacy-Code produziert: der Entwickler. In diesem Artikel möchte ich verschiedene Aspekte der Entwicklung beleuchten und an gute Softwarequalität und Arbeit appellieren.

„Das ist totaler Crap, ich würde am liebsten alles neu schreiben“, stöhnte der Azubi neben mir am Tisch, als er sich mit einer TYPO3-Extension eines aktuellen Projekts auseinandersetzen musste. Den Wunsch hört man immer häufiger. Und es gibt ja auch tatsächlich immer wieder Neuentwicklungen – egal, ob das nun Modul, Extension oder Plug-in genannt wird. Die Chancen, sich hier zu beweisen und nach den eigenen Vorstellungen arbeiten zu können, sind verlockend. Hoch motiviert geht es also ans Werk. In Zeiten von Composer kann auch eine große Bandbreite externer Libraries ohne große Aufwände zusätzlich implementiert werden. Für jeden Anwendungsfall die passende technologische Lösung, so geht Web-Development heute. Aber der Schein trügt, denn wo am Anfang der Entwicklung nichts ist, da gibt es vor allem eins: sehr viel zu tun.

Aller Anfang ist schwer

Neue Technologien und Versionen brauchen viel Erfahrung und sind bei Weitem keine Selbstläufer. Wenn aber noch keine konkreten Erfahrungen vorliegen, muss man sich diese sehr schnell erarbeiten. Hier kämpfen Entwickler also nicht nur gegen die Projektsanduhr, sondern auch gegen die eigene Ungeduld. Wurde vielleicht doch auf das falsche Pferd gesetzt …? Bis auf Weiteres ist man jedenfalls gezwungen, eine lauffähige Version mithilfe von Google und Stackoverflow zusammenzubasteln – also genau das zu tun, was man eigentlich nicht wollte.

Dies machen Entwickler bis zu einem bestimmten Punkt, auf den sie aufbauen können, denn trotz allem lässt sich auch so ein gutes Ergebnis erzielen, das jede Menge Potenzial bietet. Allerdings ist das ein Ergebnis mit Abstrichen, und zu den negativen Folgen dieser experimentellen Phase zählen Userstatements, die nicht mehr genutzt werden, Variablen- und Methodennamen, die nicht mehr treffen, und Klassen, die zu groß geworden sind. Zwar ist ersichtlich, dass gearbeitet wurde und wird – das allein ist jedoch kein Zeichen für Softwarequalität. Klar ist: Skalierbarkeit und Wartbarkeit sind zwei zentrale Ziele guter Softwareentwicklung, die nachträglich nicht implementiert werden können.

Der Plan – das Big Picture

Kleine, große und auch Teilprojekte brauchen Struktur. Wie viele Files und wie viele Zeilen Code benötige ich dafür? Allerdings sehe ich immer wieder Entwickler, die einfach drauflos coden. So entsteht Chaos. Trial-und-Error-Coder kann man diese Sorte meist junger Entwickler nennen. Im Laufe des Projekts wird es neben dem strukturellen Chaos der Files auch im Quellcode zunehmend chaotischer, und es treten unvorhersehbare Dinge ein. Häufig betrifft das vor allem die Datenmanipulation. Da ist Erfahrung gefragt: Daten müssen validiert, verändert, bereichert oder bereinigt werden und beruhen am Ende meist auf Usereingaben. Das wird von Entwicklern nur zu gerne unterschätzt.

Wichtig ist an dieser Stelle ein gutes Projektmanagement, das dafür sorgt, dass schon früh konkrete und vollständige Daten vorliegen. Häufig kommen aber auch neue Anforderungen oder Probleme ins Spiel. „Make it run“ heißt dann auf einmal die Parole – die Deadline muss unter allen Umständen eingehalten werden! Das geht natürlich auf Kosten des Entwicklers. Um dennoch die gesetzten Tagesziele zu erreichen, werden irgendwann kleine „Verfehlungen“ in Kauf genommen. Die Gründe dafür sind oft sehr facettenreich und können nicht immer erklärt werden. Beispielsweise läuft es lokal, aber nicht auf dem Staging-System. Und auch große oder viele Daten können auf einmal Probleme bereiten.

Hier gilt es dann, sehr schnell die richtigen Dinge an der richtigen Stelle zu tun. Dafür braucht man einen kühlen Kopf und wenig Files mit wenig Code in einer klaren Struktur. Nur dann ist man in der Lage, effektiv und flexibel auf solche Umstände zu reagieren. Gebastelter Code ist allerdings sehr lang und hat meist eine recht beachtliche Anzahl von if-Statements. Schlechte Lesbarkeit und hohe Komplexität können hier aber schon erheblich die Weiterentwicklung verlangsamen. Aus den besagten Gründen war der Code aber auch gar nicht darauf ausgelegt, nachhaltig zu sein, sondern er sollte nur irgendeines der vielen Tagesziele erreichen. Genau darin liegt der Fehler, der die ganze Zukunft negativ beeinflusst. Entwickler sollten das unbedingt vermeiden und von vornherein sauberen und guten Code schreiben!

Lauffähiger Code ist nicht das Maß aller Dinge

Als Webdeveloper sind wir in einer ständigen Zwickmühle – auf der einen Seite steht die Fertigstellung und auf der anderen Seite die Skalierbarkeit einer Applikation. In vielen Fällen wird es jedoch zunächst einmal nur um die Sauberkeit des Codes gehen, also um Refac­tor­ing, Clean-up oder Aufräumen. Von Skalierbarkeit ist man an diesem Punkt oft noch weit entfernt. Aus meiner Sicht ist das grundlegend falsch, und die Schuld daran trägt alleine der Entwickler. Denn klar ist: Schlechter Code wird von schlechten Entwicklern geschrieben. Hier darf es keine Ausreden geben! Aber wenn niemand sonst ein Auge darauf hat, kann auch nichts gesehen und beurteilt werden.

Quellcode sollte immer sauber und lesbar geschrieben werden, und zwar von Anfang an. Alles andere ist extrem ineffizient und nicht wirtschaftlich, auch wenn das Ganze vielleicht rein zufällig läuft. Genau das ist eine große Legacy-Code-Falle. „Any fool can write code that a computer can understand. Good programmers write code that humans can understand“, sagt der Softwarearchitekturexperte Martin Fowler dazu. Das bringt es auf den Punkt.

Guten Code schreibe ich für mich und meine Kollegen. 90 Prozent der Arbeit bestehen darin, Code zu lesen und 10 Prozent darin, ihn zu schreiben. Und das ist ein guter Wert, bei schlechtem Code liest man noch mehr und schreibt fast gar nicht mehr. Effektivität und Geschwindigkeit hole ich also nur in dem 90-Prozent-Block raus. Die Regel lautet: Kann ich meinen Code nicht gut und schnell lesen und verstehen, so kann ich auch nicht effektiv arbeiten. Hinzukommt, dass der eigentliche Code im Laufe der Zeit immer komplexer wird, da neue Anforderungen und unerwartete Herausforderungen ihn wachsen lassen. Eine Folge davon ist, dass Methoden mehr „leisten“ müssen, als es ihre eigentliche Aufgabe ist.

Datenmanipulation ist hier das Stichwort für die zahlreichen Special Cases in if-Statements. Das kann auch auf Variablennamen zutreffen, die einfach nicht mehr passen. Verschachtelte Schleifen und Statements können sogar eine erhebliche Komplexibilität aufbauen, die ohne Debugging durch einfaches Lesen nicht mehr verstanden wird. Laufen tut die Applikation trotzdem, wobei es natürlich möglich ist, dass externe Sourcen eingebunden wurden, die nicht mehr verwendet werden, aber auch nicht entfernt wurden. Datenbankfelder können überflüssig werden und vieles Weitere. Ganz schlimm sind zudem auskommentierte Codeblöcke, die ein kontinuierliches Refactoring erforderlich machen – am besten mit mindestens einem zweiten Entwickler und seiner Meinung. Sonst passiert das, was Martin Fowler sagt: „Later equals never“.

Räumen Entwickler also nicht hinter sich selbst auf, entsteht nicht selten schon nach wenigen Stunden Legacy-Code. Die Applikation ist dann nicht mehr wartbar und wird sehr teuer im Unterhalt. Typische Legacy-Fallen sind zum Beispiel:

  • wachsende Methoden

  • Varia...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang