Big Ball of Mud Development

Daniel Rosowski
Jul 23, 2017 · 7 min read

Dies ist der erste Artikel einer Serie über meine alltäglichen Projekterfahrungen als programmierender Softwarearchitekt. Meine literarischen Ergüsse haben keineswegs den Anspruch auf “original content”, sondern dienen letztlich meiner eigenen Supervision, damit ich auch in Zukunft noch mit Freuden meinem Beruf nachgehen kann. Vielleicht findet ihr ja dennoch den einen oder anderen Denkanstoß. :-)


In diesem Artikel werde ich ein wenig über die Auswirkungen eines bestimmten Architekturstils auf den Softwareentwicklungsprozess plaudern. Und nein, diesmal geht es nicht um Microservices, sondern eher um das Gegenteil. Zunächst einmal wird es den einen oder anderen vielleicht überraschen, dass der berühmt, berüchtigte Big Ball of Mud (BBoM) als ein Architekturstil bezeichnet wird, wo doch gerade der Mangel daran diese Form der Software auszeichnet.

Der Begriff BBoM wurde 1997 auf der Fourth Conference on Patterns Languages of Programs von Brian Foote und Joseph Yoder vorgestellt. Die Autoren betrachten den BBoM durchaus differenziert und stellen sich auch die Frage, aus welchem Grund dieser “Stil” so verbreitet ist. Er muss in mancher Hinsicht einiges richtig machen. Gerade in den Zeiten des Big Design Up Front, hat sich der BBoM als pragmatisch erwiesen, da eine starre Architektur für die Entwicklung hinderlich ist. Nehmen wir befestigte Wege und Trampelpfade als Analogie.

Oftmals sind die Anforderungen an ein System ungenau und werden erst mit fortschreitender Entwicklung spezifischer. Da macht es wenig Sinn, schon zu Anfang eine feste Architektur zu etablieren oder ein Design vorzuschreiben. Und manchmal braucht es vielleicht nicht mehr als einen Trampelpfad. Oder um es mit den Worten der beiden Autoren zu formulieren:

Nicht jeder Schuppen braucht Marmorsäulen.

Positiv ausgedrückt, ist der BBoM also ein schneller Weg zu einer Lösung und löst ggf. in mancherlei Hinsicht die Beschränkungen einer bestehenden Architektur. Der BBoM ist also per se nichts Schlechtes. Es ist nur wichtig, früh genug zu erkennen, wann dieser Architekturstil nicht mehr ausreicht und man sich um einen befestigten Weg bemühen sollte.


Kommen wir nun also zu den anfangs angekündigten Auswirkungen des BBoM auf den Softwareentwicklungsprozess. Die offensichtlichste Auswirkung ist die erschwerte Erweiterbarkeit einer Software, die keine klare Modularisierung erkennen lässt und wo, selbst für eine kleine Änderung, an vielen Stellen Code geändert werden muss. An dieser Stelle sollte auf die Arbeit von Industriegrößen wie David Parnas oder Edsger Dijkstra verwiesen werden, die das Thema bereits eingehend untersucht haben. Weitere Auswirkungen die ich betrachten möchte sind:

  • Releaseplanung
  • Tests
  • Buildprozess
  • Teambildung

Releaseplanung

Die Dauer und der Inhalt eines Releases sind Teil der Releaseplanung. Wenn wir in einem agilen Umfeld unterwegs sind, wird das Mantra “Release early, release often” runtergebetet. Das ist auch richtig und gut, verträgt sich aber leider gar nicht mit einem gewachsenen BBoM. Zunächst einmal kann man nur das Gesamtsystem releasen, da wir ja weder Teilsysteme noch Module haben. Hinzu kommt noch ein entsprechend langer Buildprozess (mehr dazu gleich), der das release often erheblich erschwert. Und zu guter Letzt dauern meist auch die trivialsten Änderungen wie oben erwähnt in einem BBoM einfach lange. Die Folge sind lange Releasezyklen mit dem Gefühl nicht wirklich etwas zu schaffen. Das ist sowohl für die Fachbereiche und Kunden als auch für die Entwickler frustrierend.


Tests

Mein persönliches Lieblingsthema. Die Tests sind der Puls des Softwareentwicklungsprozesses. Eine rote Buildpipeline ist ein Herzstillstand und sollte so schnell wie möglich behoben werden. Aber wieso kommt es denn zu einem roten Build? Jeder Entwickler sollte doch vor einem Commit/Push einmal die Tests laufen lassen, um sicher zu stellen, dass noch alles heile ist. Leider beeinflusst auch hier der BBoM das Thema negativ. Heutzutage arbeiten ja viele Entwickler testgetrieben, so dass dadurch eine breite Basis an automatischen Unittests entsteht. Der BBoM hat leider oft zur Folge (oder ist es die hauptsächliche Ursache?), dass die Abhängigkeiten zwischen den Klassen nicht klar definiert sind. (Wieso sollte es denn auch eine klare Trennung von Verantwortlichkeiten auf Klassenebene geben, wenn es sie auch nicht auf Modulebene gibt?) Dadurch wird die Entwicklung von Unittests erschwert, was den Entwickler dazu bringt statt “echter” Unittests eine Art Integrationstest zu schreiben. Diese haben meist eine Abhängigkeit zur Datenbank und anderen Fremdsystemen und laufen so entsprechend länger als Unittests. Die Folge davon ist, dass die Entwickler die Tests nicht mehr lokal laufen lassen, da es einfach zu lange dauert.

Ein weiteres Opfer ist die QS, die mit dem Testen einfach nicht hinterher kommt. Testautomatisierung ist zwar ein Thema was alle auf dem Schirm haben, welches sich aber als äußerst zeitintensiv und komplex erweist. Denn bei neuen Features handelt es sich in der Regel um Erweiterungen bestehender Prozesse die sich durch das gesamte System ziehen. Klare Schnittstellen und Abgrenzungen werden vergeblich gesucht. Typische Symptome sind bspw. das komplette Zurücksetzen der Datenbank vor jedem Test, da dies häufig das Einfachste Mittel ist.


Buildprozess

Eine Auswirkung des BBoM, die gerade in der heutigen Zeit von agiler Entwicklung, Continuous Integration und automatisierten Tests einen hohen Stellenwert einnimmt, ist die Dauer eines Builds. Wie lange muss ich warten, bis ich ein deploybares Artefakt bekomme? Selbst wenn ein Feature oder ein Bugfix nur einen kleinen Ausschnitt des Gesamtsystem betrifft, muss der Buildprozess für das komplette System durchlaufen werden. Neben den bereits angesprochenen langläufigen Integrationstests, beinhaltet die Buildpipeline oft auch automatisierte end-to-end Tests à la Selenium. Der ganze Buildprozess vom Push bis zum Deploy kann dann gut und gerne schonmal mehrere Stunden dauern. Das ist natürlich sehr ärgerlich, besonders wenn zum Ende hin ein Fehler in den Tests auftritt und das ganze Spiel von vorne beginnt. Die Folgen davon sind die Abschaltung bzw. Auslagerung langlaufender Tests und damit eine sinkende Gesamtqualität des Systems.


Teambildung

Der BBoM macht selbst vor den Organisationsstrukturen der Entwicklungsabteilung nicht Halt. Es lassen sich nur schwer Teams bilden die für verschiedene Aspekte des Systems verantwortlich sind, da es keine klare Trennung der Verantwortlichkeiten gibt. So wäre es z.B. sinnvoll die Stammdatenverwaltung von einem Team machen zu lassen, während sich ein anderes Team um die Batchverarbeitung kümmert. Leider sind zyklische Abhängigkeiten bei einem BBoM an der Tagesordnung, so dass beide Module voneinander abhängen und nicht unabhängig weiterentwickelt werden können. Die Folge ist ein Gesamtteam, das nicht skaliert und bei dem Themen wie Qualitätssicherung und Architektur mit zunehmender Teamgröße schwieriger werden.


Fazit

Und nun?

  1. Neu bauen
  2. Reparieren

Gerade im Bereich einer gewachsenen Anwendung im Unternehmensumfeld, ist die erste Alternative in den meisten Fällen keine Option (auch wenn ihnen externe Berater von Firmen die auch Softwareentwicklung anbieten gerne vom Gegenteil überzeugen wollen :-). Ein großer Kritiker von diesem Ansatz ist bspw. Joel Spolsky, unter anderem Mitgründer und CEO von Stackoverflow. Unterm Strich sagt er, dass ein Rewrite ein wirtschaftliches Desaster ist und nennt Netscape als Beispiel. Wenn man sich fürs “neu bauen” entscheidet, wirft man langjähriges Wissen und Bugfixes weg, die in der Software stecken. Damit gibt man seinen Wettbewerbern einen Vorsprung in der Größenordnung von Jahren, was in Software eine Ewigkeit ist.

Die zweite Alternative ist also die wirtschaftlichere Option. Auch in diesem Bereich haben sich schon einige Leute Gedanken gemacht, wie man denn eine gewachsene Software wieder in Schuß bringt. In der Regel gibt es selbst bei einem BBoM eine Soll-Architektur, wenn auch teilweise sehr versteckt. Im ersten Schritt sollte die Soll-Architektur beschrieben und kommuniziert werden. Danach gilt es die Abweichungen zwischen Soll- und Ist-Architektur zu messen und bestehende oder zukünftige Module heraus zu schneiden.

Der Begriff schneiden trifft es hier ganz richtig, da es sich meistens um einen anfangs recht schmerzhaften Prozess handelt. Nach meiner Erfahrung ist es hier eher zielführend einen umfangreichen, fachlichen Schnitt anzusetzen um damit große Teile der Funktion heraus zu lösen, als mit kleinen (meist technischen) Minimodulen zu starten. Erstens verursachen die Minimodule sehr viel Arbeit und zweitens schafft man dadurch nicht wirklich eine Verbesserung. Auch mit dem viel gehypten Thema Microservices sollte man vorsichtig sein. Man beschleunigt seinen 40 Jahre alten Käfer nicht mal eben auf 200 km/h.


Kommen ihnen die oben genannten Probleme bekannt vor? Machen Sie zusammen mit Smartsquare den Software Architektur Check und decken sie die Ursachen auf. Wir helfen ihnen dabei eine Zielarchitektur zu erarbeiten und geben ihnen konkrete Vorschläge und Maßnahmen an die Hand diese zu erreichen.

Sobald die Probleme erkannt sind und das Team gewillt ist etwas dagegen zu unternehmen, ist man auf einem guten Weg. Mit Mut, Tatkraft und Unterstützung vom Management kann man einiges bewirken.

Daniel Rosowski

Written by

Programmierender Softwarearchitekt und Geschäftsführer der Smartsquare GmbH aus Bielefeld. www.smartsquare.de

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade