Softwarewartung ist Schlammschlacht


Ralph Johnson schreibt in Antwort auf einen Post von Robert Martin einige sehr interessante Punkte dazu, wie ein Projekt in der Wartungsphase zu einem “Big Ball of Mud” werden kann, also einem Machwerk, in dem mit der Zeit jede Änderung nur noch die Gesamtfragilität des Systems erhöht, anstatt die Stabilität und Qualität zu verbessern.

Seine Kernaussage ist, dass das wirkliche Projektleben einfach so läuft, und sich viele Beispiele dessen, was eben im täglichen Projektwahnsinn passiert, nicht ein Ausfluss kollektiver Dummheit der Entwickler ist, sondern eine Folge unglücklicher Umstände und vor allem von Zeitdruck sein kann:

For example, suppose you copy a big chunk of code and then refactor it a little to eliminate duplication.  Then you realize that somebody else has also copied it, but didn’t refactor it.  And somebody else had copied it and refactored as well.  So, you need to figure out how to abstract the whole thing.  You think about it for several hours, try one thing and another, and then decide to go home and hope you think better in the morning.  But in the morning there is a crisis that you must handle.  You don’t get a chance to look at it for a few days [...]

Kommt uns das nicht irgendwie bekannt vor?

This is often how we end up with balls of mud.  As soon as we realize we are in the mud, we should try to get out.  Sometimes something else is more urgent, and we wallow in the mud for awhile.  But as long as we detect the situation when it is a small ball of mud, and don’t let it grow to a big ball of mud, we should be OK.

Die große Frage ist leider gar nicht, wie man einen solche Ansammlung schlechten Codes verhindert, schon gar nicht mehr in der Wartungsphase eines Projekts, das bereits seit 10 Jahren läuft und in dem die Urväter gar nicht mehr mitarbeiten.

Gefordert sind viel mehr Techniken, um mit dem Umstand umzugehen, dass ein System seine ganz eigenen No-go-Areas hat, also Methoden und Klassen, die möglichst niemand anfassen will, und über die man so lange gar nicht nachzudenken wagt, bis eben der Ernstfall in Form eines Tickets aus der Produktion eintritt.

Leider kostet es Aufwand, vergangene, und viel zu lange geduldete Fehlentscheidungen oder auch Code von Programmierern auszubügeln, die zu “damals” einfach nicht besser entscheiden konnten oder wollten.

Die Erkenntnis, dass man diese Problemzonen im Wartungsbudget hat, muss einfach in die Köpfe. Egal, ob man Code-Melanome entfernt oder sie ignoriert, sie werden Kosten verursachen. Sei es, weil jede kommende Änderung entweder sehr aufwändig wird, sie mehrfach durch Seiteneffekte reklamiert wird, die nicht abzusehen waren, oder aber, weil man eine Änderung dann ohnehin nur noch durch Umsetzung der notwendigen Operationen bewerkstelligen kann. Dann allerdings unter dem Druck, dass die eigentlich geforderte Änderung im (leider viel zu oft angenommenen) Idealfall gar nicht so zeitaufwändig und teuer sein kann.

Das Management eines Wartungsprojektes muss schlichtweg einen zusätzlichen Puffer bzw. zusätzliche Ressourcen für eine ständige Arbeit an der Code-Qualität einkalkulieren, die nicht auf einzelne Änderungen oder neue Anforderungen umzusetzen sind.

Schwierig wird es, diese Kosten zu beziffern oder den Aufwand zu schätzen, denn niemand kennt in einem größeren Produkt die Anzahl zu pflegender Stellen, geschweige denn ihre Auswirkungen auf Stellen, an die man nicht gleich denkt.

Aber sie sind Realität, nur eben keine manageral fassbare.

Das Problem, so denke ich zumindest, ist gar nicht so sehr ein technisches, sondern eines unserer Erwartungshaltung. Wir sind noch immer tief im Gedanken verfangen, dass Software “fertig” wird, dass neue Funktionen in der Regel “angebaut” werden können, und dass etwas, das einmal funktioniert, bei nur kleinen Änderungen weiterhin funktionieren sollte, selbst, wenn die Änderung an sich falsch durchgeführt wurde.

Wir haben eine ganze Menge Techniken, die uns Code-Verbesserungen ermöglichen, die wichtigsten (in dieser Reihenfolge) sind sicher unit tests, Refaktorisierung, Continuous Integration und so weiter. Und diese Techniken funktionieren, da sind sich, denke ich, alle einig.

Die Frage ist nur, wie setzt man sie in Projekten ein, die schon einige Jahre ohne diese Techniken gearbeitet haben? Meist lässt man es sein, weil es so viel Aufwand wäre, und wischt dabei die Möglichkeit mit vom Tisch, einfach mal an einigen wenigen Ecken damit anzufangen. Stattdessen bezahlen wir offenbar sehr gerne die horrenden Folgekosten dieser fatalen Fehlentscheidung…

About these ads