Zum Inhalt springen

Niemand hat ihn gebaut

Niemand beginnt ein Softwareprojekt mit dem Ziel, ein System zu bauen, dessen Auswirkungen zehn Jahre später kaum noch vorhersehbar sind. Unklare Verantwortlichkeiten, weitreichende Abhängigkeiten oder Bereiche, die nur noch von wenigen langjährigen Entwicklern verstanden werden, stehen in keinem Architekturkonzept als Zielbild. Am Anfang gibt es normalerweise etwas sehr viel Vernünftigeres: ein Problem, eine Idee, einen Kunden, eine Marktchance, einen Termin oder einen technisch anspruchsvollen Proof of Concept. Menschen versuchen, etwas zum Funktionieren zu bringen.

Im vorherigen Artikel ging es darum, was ein Big Ball of Mud überhaupt ist: kein Synonym für einen Monolithen, für Legacy Software oder für Technical Debt, sondern ein struktureller Zustand, in dem die beabsichtigte oder sichtbare Architektur immer weniger zuverlässig erklärt, wie das System tatsächlich organisiert ist. Daraus ergibt sich fast zwangsläufig die nächste Frage: Wie kann ein System überhaupt in diesen Zustand geraten, obwohl niemand ihn bewusst anstrebt?

Die einfache Antwort wäre eine Geschichte über schlechte Entwickler, kurzsichtiges Management oder fehlende Architekturkompetenz. Die interessantere Antwort ist schwieriger:

Ein Big Ball of Mud wird selten bewusst gebaut. Er kann über Jahre aus vielen Entscheidungen entstehen, die in ihrem jeweiligen lokalen Kontext nachvollziehbar, sinnvoll oder sogar erfolgreich waren.

Eine kleine redaktionelle Entschuldigung deshalb vorweg: Dieser Artikel ist länger als die bisherigen Beiträge der Serie. Das liegt nicht daran, dass sich die Antwort künstlich verkomplizieren ließe, sondern daran, dass gerade die Suche nach der einen Ursache schnell in die Irre führt. Es gibt nicht den einen Weg in einen Big Ball of Mud. Ein System kann schleichend erodieren, weil über Jahre lokal vernünftige Entscheidungen aufeinander aufbauen. Ein anderes wird bereits in problematischem Zustand übernommen und von einem neuen Team unter völlig anderen Vertrags- und Organisationsbedingungen weiterentwickelt. Wieder ein anderes wächst aus einem erfolgreichen Prototypen heraus, ohne dass der Übergang vom Experiment zum langlebigen Produkt strukturell nachvollzogen wird.

Diese Wege unterscheiden sich deutlich. Gemeinsam ist ihnen vor allem eine Frage: Wer besitzt über die Zeit Verantwortung für die Struktur des Gesamtsystems – und kann diese Verantwortung tatsächlich Wirkung entfalten?

Brian Foote und Joseph Yoder beginnen ihre Beschreibung des Big Ball of Mud nicht zufällig unter anderem mit Throwaway Code und dem Permanent Prototype. Ein Prototyp verfolgt ein anderes Ziel als ein langlebiges Produkt. Er soll eine Frage beantworten: Funktioniert die Idee? Ist ein Algorithmus möglich? Kann ein technisches Problem überhaupt gelöst werden? Lässt sich ein Konzept demonstrieren?

Dafür darf ein Prototyp Annahmen treffen, die man für ein Produkt möglicherweise nicht treffen würde. Er darf Wissen direkt im Code abbilden, Abstraktionen überspringen oder Strukturen verwenden, deren langfristige Wartbarkeit zunächst zweitrangig ist. Das ist kein Fehler, sondern genau der Zweck von Exploration.

Interessant wird es, wenn der Prototyp erfolgreich ist. Die Demonstration überzeugt, ein Kunde interessiert sich dafür, jemand erkennt eine Marktchance und plötzlich besitzt genau dieser Code wirtschaftlichen Wert. Wissen, Entwicklungszeit und funktionierende Lösungen stecken bereits darin. Foote und Yoder beschreiben genau diese Gefahr: Wegwerfcode wird nicht weggeworfen, weil die Alternative zunächst darin bestünde, etwas Funktionierendes noch einmal neu zu bauen. Sie behaupten damit ausdrücklich nicht, dass Prototypen zwangsläufig schlechte Produkte erzeugen. Exploration kann notwendig sein, bevor die geeignete Struktur einer Domäne überhaupt verstanden wird. Problematisch wird erst, wenn der Übergang vom Experiment zum langlebigen System strukturell nicht nachvollzogen wird.

Der Erfolg eines Proof of Concept kann genau der Grund sein, warum er nicht mehr weggeworfen wird. Erfolg konserviert frühe Entscheidungen.

Ich habe eine Variante dieser Geschichte selbst erlebt. Am Anfang stand eine wissenschaftlich und technisch außergewöhnlich anspruchsvolle Idee. Ein hochqualifizierter Wissenschaftler hatte ein schwieriges Problem gelöst und dessen technische Machbarkeit demonstriert; die wissenschaftliche Leistung dahinter war beeindruckend. Ein Unternehmer erkannte das wirtschaftliche Potenzial dieser Lösung – und auch diese Einschätzung erwies sich als richtig. Aus dem Proof of Concept wurde ein Produkt.

An welcher Stelle hätte man sagen sollen: Hier beginnt jetzt der Big Ball of Mud? An dieser jedenfalls noch nicht.

Mit einem erfolgreichen Produkt verändert sich die Situation. Ein Kunde wartet auf eine Funktion, ein Incident muss behoben werden, ein Vertrag besitzt einen Termin oder ein neues technisches Konzept ist im Team noch nicht ausreichend bekannt. Vielleicht müsste die bestehende Struktur für eine saubere Lösung zunächst umgebaut werden, während ein pragmatischer Workaround noch heute fertig werden könnte. Unter solchen Bedingungen kann der Workaround die vernünftige Entscheidung sein.

Softwareentwicklung darf nicht ausschließlich für eine hypothetische Zukunft optimiert werden. Unternehmen müssen Produkte ausliefern, Nutzer benötigen funktionierende Systeme, und ein strukturell perfekter Entwurf, der den Markt zu spät erreicht, kann wirtschaftlich die schlechtere Entscheidung sein. Auch Forschung zu Architectural Technical Debt beschreibt diese Ambivalenz: Architekturentscheidungen können zum Zeitpunkt ihrer Entstehung unter den damals bekannten Randbedingungen vertretbar sein und erst später die Weiterentwicklung behindern.

Das Problem ist deshalb nicht Pragmatismus. Die wichtigere Frage lautet, was passiert, wenn lokale Optimierung dauerhaft keine ausreichend starke strukturelle Gegenkraft besitzt. Eine Abkürzung macht noch keinen Big Ball of Mud, ein Workaround ebenso wenig, und selbst bewusst aufgenommene Technical Debt kann eine vernünftige Investitionsentscheidung sein.

Tausende Abkürzungen, die nie wieder zurückgenommen werden, können irgendwann die Architektur selbst bilden.

Die erste Sonderlösung ist meist noch eindeutig eine Sonderlösung. Vielleicht steht sogar ein Kommentar daneben:

TODO: Nach dem Release konsolidieren.

Nach dem Release kommt jedoch das nächste Feature, danach der nächste Kunde und schließlich der nächste Termin. Währenddessen verwendet bereits eine andere Änderung die ursprüngliche Sonderlösung, vielleicht hat sogar ein zweites Team begonnen, auf ihrem Verhalten aufzubauen. Was als bewusst begrenzter Workaround gedacht war, wird dadurch schrittweise zu einem Bestandteil der regulären Systemstruktur.

Aus „Das machen wir vorübergehend so“ wird „Das funktioniert bei uns so“ und irgendwann „Das haben wir schon immer so gemacht“. Genau darin liegt ein wichtiger Teil von Architekturerosion:

Architektur entsteht nicht nur durch das, was wir bewusst entwerfen. Sie entsteht auch durch das, was wir über Jahre nicht mehr zurücknehmen.

Foote und Yoders Piecemeal Growth beschreibt Softwareentwicklung dabei nicht als grundsätzlich falschen Prozess. Ein lebendes System wird schrittweise erweitert, während es weiter funktionieren muss. Die Autoren weisen jedoch auf das Risiko hin, dass akute lokale Anforderungen langfristige architektonische Anliegen verdrängen können, und stellen der Expansion deshalb wiederkehrende Consolidation Phases, Refactoring und Reparatur gegenüber.

Nicht jede Erweiterung benötigt anschließend eine große Aufräumaktion. Ein langlebiges System benötigt aber Mechanismen, durch die seine Struktur auf das Gelernte reagieren kann. Anforderungen verändern sich, Teams lernen, technische Plattformen entwickeln sich weiter, frühere Annahmen erweisen sich als falsch und fachliche Grenzen verschieben sich. Wenn sich alles um ein System herum weiterentwickelt, seine innere Struktur aber nur ergänzt und nie neu bewertet wird, konserviert es zunehmend die Vergangenheit.

Operativer Druck verändert den Entscheidungshorizont

Abschnitt betitelt „Operativer Druck verändert den Entscheidungshorizont“

Eine Deadline zerstört keine Architektur. Sie verändert jedoch, welche Lösung in einem bestimmten Moment rational erscheint. Unter operativem Druck verkürzt sich der betrachtete Zeitraum: Statt zu fragen, welche Struktur ein Bereich in drei Jahren besitzen soll, muss ein Team möglicherweise zunächst beantworten, was bis Freitag zuverlässig ausgeliefert werden kann. Das kann vollkommen legitim sein.

Die Forschung zu Zeitdruck in der Softwareentwicklung zeichnet entsprechend kein simples Bild. Ein systematischer Review von Kuutila, Mäntylä, Farooq und Claes zeigt, dass sich Zeitdruck nicht sinnvoll auf eine einfache Formel wie „mehr Druck erzeugt automatisch schlechtere Software“ reduzieren lässt; Kontext, Intensität und Art des Drucks spielen eine Rolle. Problematisch ist deshalb nicht die einzelne Deadline, sondern ein Umfeld, in dem der Entscheidungshorizont dauerhaft bei der nächsten Deadline endet.

Ähnlich verhält es sich mit dem oft kritisierten Feature-Druck. Ein Feature besitzt einen Kunden, eine konkrete Anforderung, ein Ticket, einen Termin und einen sichtbaren Nutzen. Vielleicht hängt unmittelbarer Umsatz daran, vielleicht eine regulatorische Vorgabe oder eine vertragliche Verpflichtung. Strukturelle Konsolidierung konkurriert dagegen häufig mit einem sehr viel abstrakteren Nutzen: einem zukünftigen Problem, das möglicherweise verhindert wird. Niemand kann auf einer Roadmap zeigen, welcher Incident durch ein Refactoring in vier Jahren nicht stattfinden wird.

Die Entscheidung zugunsten des Features kann deshalb wirtschaftlich vollkommen nachvollziehbar sein. Kritisch wird nicht die einzelne Priorisierung, sondern ihre Wiederholung über Jahre. Studien zu Technical Debt nennen Zeit- und Deadline-Druck sowie die Priorisierung neuer Funktionen gegenüber struktureller Qualität entsprechend häufig als Ursachen. Auch daraus folgt keine automatische Kausalkette zum Big Ball of Mud. Die interessantere Frage lautet vielmehr:

Was passiert, wenn diese Priorisierung über Jahre fast immer gleich ausfällt?

Eine mögliche Entwicklung eines Softwaresystems über viele Jahre: Ein erfolgreicher Proof of Concept wird zum Produkt, lokale Lösungen reagieren auf neue Anforderungen und Zeitdruck, Konsolidierung wird wiederholt verschoben und die innere Struktur verliert schrittweise ihre Klarheit.

Ein Big Ball of Mud muss nicht mit einer schlechten Entscheidung beginnen. Entscheidend ist, wie viele Entscheidungen über Zeit zusammenwirken.

An dieser Stelle liegt die Frage nach dem Architekten nahe: Hätte ein guter Architekt all das nicht verhindern können? Vielleicht – vielleicht aber auch nicht. Ein System benötigt nicht zwingend eine Person mit dem Titel „Softwarearchitekt“. Was es benötigt, ist eine ausreichend wirksame Gegenkraft zur permanenten lokalen Optimierung.

Diese Gegenkraft kann durch erfahrene Entwickler und Tech Leads entstehen, durch explizite Architekturregeln, Reviews, automatisierte Architekturtests oder Fitness Functions, gute Regressionstests, gemeinsame technische Prinzipien und kontinuierliches Refactoring. Sie kann auch durch eine Architekturrolle mit Zeit, Mandat und Einfluss verkörpert werden. Entscheidend ist nicht die konkrete Form, sondern ob langfristige strukturelle Qualität im entscheidenden Moment tatsächlich Gewicht besitzt.

Ein Architekt allein verhindert keinen Big Ball of Mud. Eine Person, die zwar verantwortlich genannt wird, aber weder Zeit noch Entscheidungsspielraum besitzt, kann eine Systemstruktur kaum dauerhaft schützen. Umgekehrt können erfahrene Teams ohne formale Architektenrolle über lange Zeit ausgezeichnete Systeme entwickeln.

Entscheidend ist weniger der Titel „Architekt“ als die Frage, ob langfristige strukturelle Qualität im System eine wirksame Vertretung besitzt.

Die systematische Mapping Study von Li, Liang, Soliman und Avgeriou ist in diesem Zusammenhang besonders relevant. Ihre Auswertung von 73 Studien zu Architecture Erosion kommt ausdrücklich zu dem Ergebnis, dass nichttechnische Ursachen ebenso ernst genommen werden sollten wie technische. Architekturerosion lässt sich deshalb nicht sinnvoll auf Codequalität oder einzelne Designentscheidungen reduzieren.

Damit komme ich noch einmal zu dem Produkt zurück, dessen Ursprung ich selbst später kennengelernt habe. Seine technische Grundlage entstand aus wissenschaftlich außergewöhnlich anspruchsvoller Arbeit. Derjenige, der den ursprünglichen Ansatz entwickelte, löste ein Problem, das nur sehr wenige Menschen überhaupt hätten lösen können. Danach erkannte jemand anderes das wirtschaftliche Potenzial dieser Idee. Auch dafür braucht es Expertise: Märkte verstehen, Chancen erkennen, Risiken eingehen und aus einer technischen Möglichkeit ein Produkt machen.

Beides war erfolgreich. Beides ist jedoch etwas anderes als die Frage, wie man ein Softwaresystem strukturiert, das über Jahrzehnte von wechselnden Teams weiterentwickelt werden soll.

Expertise ist domänenspezifisch.

Ein hervorragender Mathematiker ist nicht automatisch Softwarearchitekt, und ein visionärer Unternehmer ist nicht automatisch Experte für evolutionäre Softwarearchitektur. Umgekehrt würde ich mir nicht zutrauen, die wissenschaftliche Arbeit eines Kryptografen oder die Marktentscheidung eines erfolgreichen Gründers besser zu treffen, nur weil ich Softwaresysteme strukturieren kann. Problematisch wird es erst, wenn Organisationen diese Kompetenzen miteinander verwechseln oder davon ausgehen, außergewöhnliche Intelligenz und hoher persönlicher Einsatz könnten strukturelle Defizite auf Dauer ersetzen.

Das funktioniert nämlich erstaunlich oft zunächst. Sehr gute Entwickler können schwierige Systeme lange beherrschbar halten, weil sie Sonderfälle verstehen, historische Entscheidungen kennen, Migrationen bauen, Releases retten und Wege durch Strukturen finden, die sich anderen kaum noch erschließen. Das ist Kompetenz – und genau diese Kompetenz kann paradoxerweise dazu beitragen, dass die Grenzen des Systems lange nicht vollständig sichtbar werden. Solange sehr gute Menschen immer wieder eine Lösung finden, liefert das System weiterhin Ergebnisse. Aus Sicht des nächsten Releases gibt es damit zunächst einen guten Grund, genauso weiterzumachen.

Ein weiterer Mechanismus lässt sich besonders gut an langlebigen Frameworks und Plattformen beobachten, ist aber keineswegs auf ein bestimmtes Frontend-Framework beschränkt. Eine Plattform stellt Konzepte, Erweiterungspunkte und Lebenszyklen bereit. Ein Team versteht eine dieser Mechaniken möglicherweise noch nicht ausreichend, hält sie für ungeeignet oder besitzt unter Zeitdruck nicht die Möglichkeit, sie sauber zu integrieren. Also entsteht eine eigene Lösung – und diese Lösung kann durchaus gut funktionieren.

Daran ist zunächst nichts grundsätzlich falsch. Frameworks treffen keine unfehlbaren Architekturentscheidungen, und eigene Abstraktionen können sinnvoll oder sogar notwendig sein. Entscheidend ist, was danach passiert. Die Plattform entwickelt sich weiter, Konzepte werden verändert, APIs ersetzt, frühere Mechanismen deprecated oder entfernt. Die eigene Lösung passt irgendwann nicht mehr zum vorgesehenen Evolutionspfad und muss entweder angepasst werden – oder der neue Plattformmechanismus wird erneut umgangen.

Wird dieser zweite Weg wiederholt gewählt, kann eine Verstärkung entstehen:

Abweichung → Upgrade-Problem → Workaround → größere Abweichung → größeres Upgrade-Problem

Irgendwann wartet das Team nicht mehr nur sein Produkt, sondern zusätzlich Teile einer selbst geschaffenen Parallelplattform. Der relevante Unterschied liegt daher nicht darin, ob jede Framework-Vorgabe richtig ist, sondern in der langfristigen Abkopplung vom Evolutionspfad der gewählten Plattform.

Auch das war in dem System, das ich erlebt habe, kein einzelner großer Fehler. Nach einem Technologiewechsel besaß das Team begrenzte Erfahrung mit der neuen Plattform und gleichzeitig realen Lieferdruck. Wo vorgesehene Mechanismen nicht verstanden, nicht akzeptiert oder nicht rechtzeitig integriert werden konnten, entstanden eigene Lösungen. Sie funktionierten, wurden deshalb weiterverwendet und mussten bei späteren Plattformversionen erneut geschützt oder angepasst werden.

Auch an diesem Punkt hätte niemand auf einen einzelnen Commit zeigen und sagen können: Hier wurde der Big Ball of Mud gebaut. Jede Änderung hatte eine Geschichte.

Während all das geschieht, verändert sich die Organisation. Entwickler wechseln das Team oder das Unternehmen, Tech Leads gehen, Product Owner ändern sich, Führungskräfte kommen und gehen, Strategien werden neu formuliert und Technologien verlieren oder gewinnen an Bedeutung. Der Code bleibt.

Mit Menschen verschwinden nicht nur technische Fähigkeiten, sondern häufig auch Teile des Wissens darüber, warum eine bestimmte Entscheidung getroffen wurde. Ein Entwickler wusste vielleicht genau, dass eine Lösung nur existieren sollte, bis ein bestimmtes anderes Problem gelöst war. Jahre später kennt niemand mehr dieses Problem, die Lösung existiert aber weiterhin. Damit verändert sich ihre Bedeutung: Aus einer bewusst akzeptierten Ausnahme kann eine vermeintliche Konvention werden, auf der die nächste Generation weiterbaut.

Software besitzt häufig ein längeres Gedächtnis als Organisationen. Der Code bewahrt Entscheidungen, deren ursprüngliche Begründung längst verloren gegangen ist.

Bis hierhin beschreibt der Artikel einen klassischen Erosionspfad: Ein System wächst, verändert sich, sammelt Entscheidungen und verliert über Zeit einen Teil seiner ursprünglichen Struktur. Aber das ist nicht der einzige Weg.

Nicht jedes Team beginnt seine Arbeit an einem System, als dieses noch strukturell gesund war. Manchmal ist der Big Ball of Mud bereits da. Ein neues Team übernimmt eine bestehende Anwendung – nach einer internen Reorganisation, durch einen Dienstleisterwechsel oder im Rahmen eines neuen Projekts. Vielleicht wird die nächste Version eines langlebigen öffentlichen Informationssystems ausgeschrieben und ein anderer Auftragnehmer erhält den Zuschlag.

Dieses Team sitzt dann vor einer Codebasis, deren Entscheidungen es nicht getroffen hat. Die Module, Abhängigkeiten, fehlenden Tests und historischen Workarounds existieren bereits; nur der Kontext ihrer Entstehung ist teilweise verschwunden. Das verändert die Schuldfrage fundamental. Das neue Team hat den Big Ball of Mud nicht gebaut, muss aber trotzdem darin arbeiten.

Damit stellt sich eine neue Frage:

Besitzt dieses Team überhaupt den Auftrag, die strukturellen Probleme zu beheben – oder nur den Auftrag, die nächste Funktion darin zu implementieren?

Der Konflikt wird besonders sichtbar, wenn langlebige Software in zeitlich begrenzten Projekten organisiert wird. Organisatorisch kann Version 1 abgeschlossen und abgenommen sein; technisch lebt dasselbe System weiter. Version 2 kann einen neuen Vertrag, ein neues Budget und einen neuen Auftragnehmer besitzen, übernimmt aber dennoch alle technischen Entscheidungen aus Version 1. Die Projektgrenze existiert im Vertrag – im Code existiert sie nicht.

Das klingt banal, verändert in der Praxis aber die Anreizstruktur erheblich. Ein Auftragnehmer entwickelt V1, das System erfüllt seine fachliche Funktion und wird abgenommen. Einige Jahre später wird V2 beauftragt und ein neuer Auftragnehmer übernimmt. Dieser stellt fest, dass wesentliche Bereiche schlecht dokumentiert sind, Tests fehlen und die Struktur erhebliche Defizite besitzt. Seine technische Einschätzung kann lauten:

Bevor wir darauf langfristig weiterbauen, müssten wir Teile davon konsolidieren.

Der kommerzielle Auftrag lautet aber möglicherweise schlicht:

Liefert V2.

Damit entsteht ein Satz, der in solchen Situationen keineswegs absurd sein muss:

„Wir werden nicht für Refactoring bezahlt.“

Das ist nicht automatisch eine Ausrede, sondern kann eine vollkommen korrekte Beschreibung des Vertrags sein. Das Architekturproblem ist dann nicht unbekannt – es besitzt nur keinen finanzierten Owner.

Für den neuen Auftragnehmer entsteht daraus ein schwieriges ökonomisches Problem. Er übernimmt die technische Vergangenheit des Produkts, während sein Auftrag möglicherweise primär die nächste fachliche Erweiterung finanziert. Soll er auf eigene Kosten die Architektur seines Vorgängers sanieren? Soll er erklären, dass ein erheblicher Teil des Budgets nicht in sichtbare neue Funktionalität, sondern in strukturelle Arbeit fließen sollte? Und was passiert, wenn genau diese Arbeit nicht Bestandteil der Ausschreibung war und andere Anbieter deshalb günstiger kalkuliert haben?

Unter solchen Bedingungen kann das lokale Weiterbauen erneut die wirtschaftlich rationale Entscheidung sein. Strukturell ist das fast dieselbe Logik wie beim Feature-Druck innerhalb eines Unternehmens – nur an einer härteren Grenze. Der Auftragnehmer optimiert auf seinen Leistungsumfang, die Fachseite auf benötigte Funktionalität, die Projektleitung auf Termin, Budget und Abnahme und die Vergabestelle auf ein korrektes Verfahren. Alle Beteiligten können ihre jeweilige Aufgabe vernünftig erfüllen, während langfristige Architekturqualität zwischen diesen Verantwortlichkeiten verschwindet.

Jedes Projekt kann erfolgreich sein, während das Produkt gleichzeitig erodiert.

Die lokale Einheit ist hier nicht mehr ein Feature oder ein Team, sondern ein vollständiges Projekt.

Öffentliche Beschaffung macht diesen Konflikt besonders sichtbar

Abschnitt betitelt „Öffentliche Beschaffung macht diesen Konflikt besonders sichtbar“

Dieser Mechanismus ist nicht auf den Public Sector beschränkt. Auch Unternehmen wechseln Dienstleister, schneiden Budgets in Projekte oder kaufen Softwareentwicklung paketweise ein. Im öffentlichen Bereich tritt der Konflikt jedoch besonders deutlich hervor, weil Vergabe, Wettbewerb, Haushaltslogik und Softwareentwicklung gleichzeitig erfüllt werden müssen.

Forschung zu öffentlichen Informationssystemen beschreibt genau diese Spannungen. Alaranta und Jarvenpaa untersuchten bereits 2010 den Wechsel eines langfristigen IT-Dienstleisters bei einer öffentlichen Organisation in Finnland. Der Wechsel wurde nicht durch schlechte Leistung des bisherigen Anbieters ausgelöst, sondern durch den öffentlichen Beschaffungsprozess. Im Zentrum ihrer Fallstudie steht der Verlust von Erfahrungswissen beim Übergang von einem Anbieter zum nächsten.

Das ist ein wichtiger Unterschied zu einer rein technischen Übergabe. Source Code lässt sich kopieren, Tickets lassen sich exportieren und Dokumentation lässt sich übergeben. Erfahrungswissen lässt sich nicht vollständig als Artefakt exportieren.

Noch grundsätzlicher formulieren Ghezzi und Kollegen das Problem: Software besitzt sowohl die Möglichkeit als auch die Notwendigkeit kontinuierlicher Veränderung, während öffentliche Informationssysteme gleichzeitig an Wettbewerbs- und Budgetierungsprozesse gebunden sind. Damit treffen zwei unterschiedliche Zeitmodelle aufeinander. Die Software entwickelt sich kontinuierlich weiter; Finanzierung, Vergabe und Verantwortlichkeiten werden dagegen häufig in Perioden und Projekten organisiert.

Auch Moe, Newman und Sein zeigen in ihrer Untersuchung öffentlicher Informationssystembeschaffung einen institutionellen Zielkonflikt. Ein Auftraggeber benötigt für komplexe Systeme häufig intensiven Dialog, um Anforderungen überhaupt ausreichend verstehen und spezifizieren zu können. Gleichzeitig begrenzen Vergaberegeln diesen Dialog aus guten Gründen, weil Transparenz und Gleichbehandlung der Anbieter erhalten bleiben müssen.

Das Problem lässt sich deshalb nicht auf den Satz reduzieren, öffentliche Auftraggeber müssten einfach bessere Ausschreibungen schreiben. Die Anforderungen an rechtskonforme und faire Beschaffung und die lernende, evolutionäre Natur komplexer Software stehen teilweise tatsächlich in Spannung. Genau deshalb wird langfristige technische Ownership wichtiger, nicht weniger wichtig.

Wer besitzt die Architektur zwischen zwei Ausschreibungen?

Abschnitt betitelt „Wer besitzt die Architektur zwischen zwei Ausschreibungen?“

Wenn Auftragnehmer wechseln können, muss deshalb jemand anderes die Struktur des Systems über diese Wechsel hinweg vertreten. Der erste Auftragnehmer kann diese Rolle nicht dauerhaft übernehmen, weil sein Vertrag endet. Der nächste hat die ursprünglichen Entscheidungen nicht getroffen. Die Fachseite besitzt möglicherweise exzellente Domänenkenntnis, aber nicht zwingend tiefe Softwarearchitekturkompetenz. Eine Projektleitung kann Budgets, Termine und Stakeholder hervorragend steuern, ohne deshalb eine Dependency-Struktur oder Teststrategie fachlich bewerten zu können. Auch die Vergabestelle verfolgt eine andere Aufgabe.

Das bedeutet nicht, dass öffentliche Auftraggeber technisch inkompetent sein müssen. Es bedeutet lediglich, dass langlebige Softwarearchitektur eine Kompetenz benötigt, die nicht automatisch aus klassischer Projektorganisation entsteht.

Der Auftragnehmer kann wechseln. Die Architektur-Ownership darf nicht jedes Mal neu beginnen.

Diese Ownership bedeutet nicht, dass jede Zeile Code intern geschrieben werden muss. Entwicklung kann weiterhin extern erfolgen, Teams und Dienstleister können wechseln. Aber irgendwo auf Auftraggeberseite muss langfristig ausreichend technische Kompetenz erhalten bleiben, um fachliche und technische Grenzen zu vertreten, Qualitätsanforderungen festzulegen, Technical Debt bewusst zu akzeptieren oder zurückzuweisen und zu entscheiden, welche Sanierungsarbeiten bereits Bestandteil einer Ausschreibung sein müssen.

Dazu gehört auch, verbindlich zu klären, welche Tests und automatisierten Qualitätsmechanismen bei jeder Übergabe vorhanden sein müssen, welche Architekturentscheidungen gelten, welche strukturellen Risiken der neue Auftragnehmer übernimmt und welcher Zustand überhaupt als abnahmefähig gilt. Das ist mehr als Projektsteuerung. Es ist Produkt- und Architektur-Ownership über Vertragsgrenzen hinweg.

Eine langlebige Software verläuft als durchgehende Linie durch drei zeitlich getrennte Projekte. Projekt V1 wird von Auftragnehmer A entwickelt, V2 von Auftragnehmer B und V3 von Auftragnehmer C. Mit jedem Projekt endet der jeweilige Vertrag, während Code, Abhängigkeiten und technische Entscheidungen in das nächste Projekt weiterwandern.

Projekt- und Vertragsgrenzen schneiden die Organisation. Die technische Vergangenheit des Produkts überschreitet diese Grenzen jedoch vollständig.

Eine einfache Schlussfolgerung wäre nun, Software dürfe eben nie ausgelagert werden. Auch das wäre zu kurz gegriffen. Externe Entwicklung kann Zugang zu Spezialwissen schaffen, Kapazitäten flexibel verfügbar machen und Organisationen bei Aufgaben unterstützen, die intern nicht sinnvoll aufgebaut werden können. Das eigentliche Risiko liegt nicht in der Existenz eines externen Dienstleisters, sondern darin, dass mit der Entwicklung zugleich die Fähigkeit zur technischen Steuerung verloren geht.

Ein Auftragnehmer arbeitet jeden Tag am System. Er versteht seine Sonderfälle, kennt die Stellen, an denen Dokumentation und Realität auseinanderlaufen, und weiß, welcher Test nur auf dem Papier Sicherheit erzeugt oder welches Modul besser nicht verändert wird. Wenn dieses Wissen ausschließlich beim Lieferanten entsteht, wird ein späterer Wechsel schwieriger. Dafür braucht es keine bewusste Lock-in-Strategie; es reicht, wenn der Auftraggeber über Jahre keine ausreichende eigene technische Kompetenz aufbaut oder erhält.

Auch deshalb ist neuere Forschung zum Backsourcing interessant. Lassenius, Mohagheghi und Seide Molléri untersuchten eine große öffentliche Organisation, die die Verantwortung für einen erheblichen Teil ihrer Softwareentwicklung wieder stärker ins eigene Haus holte. Zu den berichteten Ergebnissen gehörten unter anderem stärkeres System-Ownership, mehr Kontrolle über den Lebenszyklus, schnellere Lieferung und eine stärkere Fokussierung auf Technical Debt. Gleichzeitig zeigt die Studie, wie anspruchsvoll es ist, die dafür notwendigen Kompetenzen wieder aufzubauen und dauerhaft zu halten.

Die Pointe ist deshalb nicht, dass Insourcing grundsätzlich besser wäre. Sie lautet vielmehr:

Wer Softwareentwicklung auslagert, darf die Fähigkeit zur technischen Ownership nicht automatisch mit auslagern.

Damit bekommt der Satz „Wir werden nicht für Refactoring bezahlt“ eine zweite Bedeutung. Im ersten Entstehungspfad dieses Artikels wurde Refactoring verschoben, weil das nächste Feature dringender erschien. Im zweiten Pfad kann Refactoring bereits außerhalb des vereinbarten Leistungsumfangs liegen. Das Team erkennt die strukturelle Notwendigkeit möglicherweise sehr genau und besitzt sogar die Kompetenz dafür, aber die kommerzielle Struktur des Projekts bietet keinen Raum.

Das macht die Situation nicht unvermeidbar. Technische Qualität, Wartbarkeit, Tests, Dokumentation, Architekturregeln und Sanierungsarbeiten können Gegenstand von Ausschreibungen und Verträgen sein. Dafür muss der Auftraggeber jedoch zunächst erkennen, welche Qualität er benötigt, sie beschreiben können und ihre Einhaltung fachlich bewerten.

Qualität lässt sich nur wirksam beauftragen, wenn jemand auf Auftraggeberseite versteht, welche Qualität eigentlich benötigt wird.

Genau hier schließt sich der Kreis zur Architektur-Ownership.

Der klassische Erosionspfad und der projektweise Übergabepfad unterscheiden sich deutlich. Im ersten Fall wächst ein System über Jahre in seine Probleme hinein; im zweiten übernimmt ein neues Team einen Teil dieser Probleme bereits am ersten Tag. Im ersten verlieren Workarounds langsam ihren Ausnahmecharakter, im zweiten erscheinen sie dem neuen Team von Anfang an schlicht als Bestand. Im ersten verschiebt dieselbe Organisation Refactoring immer wieder zugunsten neuer Anforderungen, im zweiten kann ein neuer Auftragnehmer feststellen, dass Refactoring notwendig wäre, dafür aber überhaupt nicht beauftragt worden sein.

Trotzdem besitzen beide Wege einen gemeinsamen Kern:

Die Lebensdauer struktureller Entscheidungen ist länger als die Lebensdauer der Verantwortung, die für sie vorgesehen wurde.

Feature-Teams lösen sich auf, Architekten wechseln, Aufträge enden, Dienstleister verlieren die nächste Ausschreibung und Projektphasen werden abgenommen. Der Code, die Abhängigkeiten und ihre Folgen bleiben. Langfristige Architektur-Ownership ist deshalb nicht einfach eine Rolle in einem Organigramm, sondern eine Kontinuitätsfunktion. Jemand – oder eine wirksame Kombination aus Menschen, Regeln und automatisierten Mechanismen – muss über Zeit dafür sorgen, dass die Summe lokaler Entscheidungen noch mit einer tragfähigen Gesamtstruktur vereinbar bleibt.

Wenn die Vergangenheit die nächste Entscheidung diktiert

Abschnitt betitelt „Wenn die Vergangenheit die nächste Entscheidung diktiert“

Mit zunehmender Erosion verändert sich außerdem der Raum zukünftiger Entscheidungen. Eine neue Anforderung startet nicht mehr auf einem leeren Blatt, sondern trifft auf bestehende Kopplungen, Sonderlösungen, Eigenmechanismen, Migrationen und historische Annahmen. Dadurch kann eine Rückkopplung entstehen:

Zeitdruck
→ lokale Lösung
→ zusätzliche strukturelle Abhängigkeit
→ nächste Änderung benötigt mehr Analyse
→ Aufwand und Risiko steigen
→ Zeitdruck steigt
→ lokale Lösung wird erneut besonders attraktiv

Martini, Bosch und Chaudron beobachteten in einer Mehrfachfallstudie in großen Unternehmen genau solche zeitlichen Dynamiken bei Architectural Technical Debt. Refactoring wurde in den untersuchten Unternehmen häufig reaktiv durch Krisen ausgelöst, statt strukturelle Verschuldung kontinuierlich sichtbar und steuerbar zu halten.

Die Schleife ist nicht zwangsläufig. Sie kann unterbrochen werden, benötigt dafür aber eine Gegenbewegung: Konsolidierung, Refactoring, Architekturarbeit, bewusstes Entfernen nicht mehr sinnvoller Strukturen – und vor allem jemanden, der dafür tatsächlich Verantwortung, Zeit und Budget besitzt.

Verstärkungsschleife eines erodierenden Systems: Zeitdruck begünstigt eine lokale pragmatische Lösung, zusätzliche strukturelle Abhängigkeiten erhöhen später Änderungsaufwand und Risiko, wodurch bei der nächsten Änderung erneut stärkerer Zeitdruck entsteht.

Lokale Lösungen können zukünftige Entscheidungen verändern: Wird das System schwieriger zu ändern, steigt der Druck, beim nächsten Mal erneut lokal zu optimieren.

Die Vergangenheit bestimmt die Zukunft nicht vollständig, aber sie verändert ihren Preis.

Und jetzt werden lokale Entscheidungen noch schneller

Abschnitt betitelt „Und jetzt werden lokale Entscheidungen noch schneller“

Coding Agents verändern an diesem Grundproblem zunächst vor allem eine Variable: Geschwindigkeit. Ein Agent kann in beeindruckender Geschwindigkeit eine lokal funktionierende Lösung erzeugen. Wenn Ownerships, Grenzen und Architekturregeln eindeutig sind, ist genau das ein großer Vorteil. Fehlen diese Orientierungspunkte, muss auch ein Agent bei jeder Aufgabe neu interpretieren, welche der vielen möglichen lokalen Lösungen strukturell erwünscht ist.

Ein Agent kann sehr schnell gute lokale Lösungen finden. Genau das war historisch schon Teil des Problems.

Darauf wird diese Serie an anderer Stelle noch ausführlicher zurückkommen.

Nach all diesen Geschichten liegt die Frage nahe, wer nun eigentlich schuld ist. „Niemand“ wäre eine bequeme Antwort, würde Verantwortung aber vollständig auflösen. Entscheidungen haben Verantwortliche: Entwickler tragen Verantwortung für ihre Änderungen, technische Führung für technische Richtungsentscheidungen, Management für Prioritäten und Auftraggeber für Anforderungen und Verträge. Auftragnehmer wiederum verantworten die Qualität der vereinbarten Leistung.

„Alle“ wäre allerdings ebenso wenig hilfreich. Menschen handeln zu unterschiedlichen Zeitpunkten mit unterschiedlichen Informationen, Zwängen, Budgets und Zeithorizonten. Der Entwickler, der einen Workaround baut, kennt möglicherweise die Deadline, aber nicht die Anforderungen der nächsten fünf Jahre. Der Product Owner sieht den Kunden, der auf ein Feature wartet, aber nicht jede daraus entstehende technische Abhängigkeit. Der Architekt kennt die langfristige Zielstruktur, besitzt aber vielleicht nicht das Mandat, sie gegen jede kurzfristige Priorität durchzusetzen. Ein neuer Auftragnehmer erkennt einen strukturell problematischen Bestand, hat aber möglicherweise nur Budget für die nächste Version.

Auch Projektmanagement und Softwarearchitektur sind unterschiedliche Kompetenzen. Eine Projektleitung kann ihre Aufgabe professionell erfüllen und trotzdem nicht die fachliche Tiefe besitzen, eine komplexe Dependency-Struktur oder die Tragfähigkeit einer Teststrategie selbst zu beurteilen. Das ist kein persönliches Versagen, sondern zunächst eine Frage der Rollen und der dafür notwendigen Expertise.

Deshalb lässt sich der Big Ball of Mud als Gesamtzustand häufig nicht sinnvoll auf eine einzelne Person oder eine einzelne Entscheidung reduzieren. Genau darin unterscheidet sich Verantwortung von Schuldzuweisung: Entscheidungen lassen sich kritisch analysieren, ohne daraus eine Tätergeschichte zu machen.

Wenn ich heute auf Systeme zurückblicke, die mich zu dieser Serie gebracht haben, fällt es mir schwer, den Moment zu finden, an dem man eindeutig hätte sagen können: Jetzt ist daraus ein Big Ball of Mud geworden. Der erfolgreiche Proof of Concept war es nicht; ohne ihn hätte es das Produkt möglicherweise nie gegeben. Auch die Entscheidung zur Produktisierung kann wirtschaftlich vollkommen richtig gewesen sein. Der erste Workaround löste vermutlich ein reales Problem, der Technologiewechsel hatte nachvollziehbare Gründe und das verschobene Refactoring verlor vielleicht tatsächlich gegen einen Kunden, der in diesem Moment wichtiger war.

Beim geerbten System wird die Frage noch schwieriger. Ist Firma B schuld, weil sie auf V1 weiterbaut, wenn ihr Auftrag schlicht darin besteht, V2 zu liefern? Ist Firma A schuld, wenn sie genau die Qualitätsanforderungen erfüllt hat, die damals beauftragt und abgenommen wurden? Ist die Projektleitung verantwortlich für eine technische Struktur, wenn ihr die Rolle und Kompetenz fehlt, Architekturqualität über mehrere Vergabezyklen hinweg zu vertreten?

Genau deshalb ist die Entstehung eines Big Ball of Mud so interessant:

Es ist nicht der eine Fehler. Es ist das Zusammenspiel vieler lokal logischer Entscheidungen über Jahre.

Manchmal kommt noch etwas hinzu:

Die Organisation kann ihre Verantwortung in Projekte schneiden. Das Softwaresystem übernimmt diese Schnitte nicht.

Foote und Yoder fragten schon Ende der 1990er-Jahre, welche Kräfte gute Programmierer dazu bringen, strukturell problematische Systeme hervorzubringen. Ihre Beschreibung von Throwaway Code, Piecemeal Growth, Keep It Working, Shearing Layers, Konsolidierung und schließlich Reconstruction liest sich weniger wie ein Katalog individueller Fehler als wie eine Beschreibung evolutionärer Kräfte, die auf langlebige Software wirken.

Die heutige Forschung zu Architecture Erosion, Architectural Technical Debt, Outsourcing und öffentlichen Informationssystemen erweitert dieses Bild. Sie zeigt technische und nichttechnische Einflussfaktoren, konkurrierende kurz- und langfristige Ziele, Wissensverlust bei Übergaben, institutionelle Zielkonflikte in der Beschaffung und den Wert langfristigen System-Ownerships.

Ein Big Ball of Mud kann deshalb als emergentes Ergebnis verstanden werden: Viele Beteiligte verändern ein System über einen langen Zeitraum, und jede Änderung reagiert auf die Situation, die vorherige Änderungen geschaffen haben. Teams, Verträge und Organisationen wechseln, während technische Entscheidungen weiterleben. Ohne kontinuierliche strukturelle Rückkopplung kann die Summe irgendwann eine Form annehmen, die niemand als Zielbild entworfen hätte.

Jeder hat vielleicht ein Stück beigetragen, manche haben nur ein bereits vorhandenes Stück weitergetragen. Niemand hat das Ergebnis gezeichnet, niemand hat an einem Tag beschlossen, seine Grenzen aufzulösen.

Und trotzdem haben viele Menschen – meistens aus nachvollziehbaren Gründen – ein kleines Stück zu ihm beigetragen.

Architekturerosion ist kein Ereignis. Sie ist ein Prozess. Und manchmal ist das Wichtigste, was eine Organisation dagegen tun kann, erstaunlich unspektakulär:

Dafür sorgen, dass die Verantwortung für die Architektur länger lebt als das nächste Feature, das nächste Projekt, das nächste Team oder der nächste Vertrag.

  • Brian Foote, Joseph W. Yoder: Big Ball of Mud. Technical Report WUCS-97-34, Department of Computer Science, Washington University, ursprünglich vorgestellt auf der Fourth Conference on Pattern Languages of Programs (PLoP ’97), 1997; später als Kapitel 29 in Neil Harrison, Brian Foote, Hans Rohnert (Hrsg.): Pattern Languages of Program Design 4. Addison-Wesley, 2000.
  • Ruiyin Li, Peng Liang, Mohamed Soliman, Paris Avgeriou: Understanding Software Architecture Erosion: A Systematic Mapping Study. Journal of Software: Evolution and Process 34(3), 2022, e2423. DOI: 10.1002/smr.2423.
  • Antonio Martini, Jan Bosch, Michel Chaudron: Investigating Architectural Technical Debt Accumulation and Refactoring over Time: A Multiple-Case Study. Information and Software Technology 67, 2015, S. 237–253. DOI: 10.1016/j.infsof.2015.07.005.
  • Roberto Verdecchia, Philippe Kruchten, Patricia Lago, Ivano Malavolta: Building and Evaluating a Theory of Architectural Technical Debt in Software-Intensive Systems. Journal of Systems and Software 176, 2021, 110925. DOI: 10.1016/j.jss.2021.110925.
  • Miikka Kuutila, Mika Mäntylä, Umar Farooq, Maëlick Claes: Time Pressure in Software Engineering: A Systematic Review. Information and Software Technology 121, 2020, 106257. DOI: 10.1016/j.infsof.2020.106257.
  • Rodrigo Rebouças de Almeida, Christoph Treude, Uirá Kulesza: What’s Behind Tight Deadlines? Business Causes of Technical Debt. IEEE/ACM International Conference on Cooperative and Human Aspects of Software Engineering (CHASE), 2023.
  • Robert Ramač et al.: Prevalence, Common Causes and Effects of Technical Debt: Results from a Family of Surveys with the IT Industry. Journal of Systems and Software 184, 2022, 111114. DOI: 10.1016/j.jss.2021.111114.
  • Martin P. Robillard: Turnover-Induced Knowledge Loss in Practice. ESEC/FSE ’21, 2021, S. 1292–1302. DOI: 10.1145/3468264.3473923.
  • Maria Alaranta, Sirkka L. Jarvenpaa: Changing IT Providers in Public Sector Outsourcing: Managing the Loss of Experiential Knowledge. 43rd Hawaii International Conference on System Sciences (HICSS), 2010. DOI: 10.1109/HICSS.2010.101.
  • Reetta Ghezzi, Aapo Koski, Janne Lautanala, Mikko Lehtisalo, Manu Setälä, Tommi Mikkonen: Towards Sustainable Software for Public Sector Information Systems. IEEE/ACM International Conference on Software and System Processes (ICSSP), 2023, S. 86–91. DOI: 10.1109/ICSSP59042.2023.00019.
  • Carl Erik Moe, Michael Newman, Maung Kyaw Sein: The Public Procurement of Information Systems: Dialectics in Requirements Specification. European Journal of Information Systems 26(2), 2017, S. 143–163. DOI: 10.1057/s41303-017-0035-4.
  • Josep M. Marco-Simó, Joan A. Pastor-Collado: IT Outsourcing in the Public Sector: A Descriptive Framework from a Literature Review. Journal of Global Information Technology Management 23(1), 2020, S. 25–52. DOI: 10.1080/1097198X.2019.1701357.
  • Casper Lassenius, Parastoo Mohagheghi, Jefferson Seide Molléri: Bringing it Home: Successful Backsourcing of Software Development in the Public Sector. Empirical Software Engineering 30, 170, 2025. DOI: 10.1007/s10664-025-10722-1.