Microservices und ihre Alternativen

Code-Monolithen

von - 23.08.2021
Das Ganze macht aber noch nicht unbedingt ein Anti-Pattern, sondern soll zunächst nur die Nachteile des Architekturmusters aufzeigen. Die Erklärungen deuten dabei aber bereits an, wie fliessend der Übergang zwischen Pattern und Anti-Pattern sein kann (vgl. Kasten Pattern versus Anti-Pattern). Einen Fall, in dem deutlichere Zeichen eines Anti-Patterns zu erkennen sind, wollen wir nachträglich als Sourcecode-Monolithen bezeichnen. In diesem Fall findet sich der gesamte Code der Applikation in einer einzelnen Codebasis wieder, auf der auch alle Entwickler zeitgleich und ohne grössere Abgrenzung arbeiten und die intern so stark verwoben ist, dass man Bestandteile nur sehr schwer aus ihr herauslösen kann.
Zugegeben, sowohl Microsoft als auch Google folgen einem ähnlichen Vorgehen für sehr grosse Softwareprojekte, und der Begriff des Mono-Repos (Monolithic Repository) beschreibt ein sehr ähnliches Vorgehen, das gerade in der Webentwicklung einigen positiven Zuspruch erhält. Hierbei arbeiten dann verschiedene Teams an verschiedenen Bestandteilen eines verteilten Softwaresystems, teilen sich aber ein grosses Code-Repository. Dies hat zum Beispiel den Vorteil, dass der gesamte Code zeitgleich zur Verfügung steht und man «mal eben nachschauen» kann, wie denn eine Methode konkret umgesetzt ist, die man verwenden will.
Sind in diesem Zusammenhang aber keine organisatorischen oder technischen Grenzen etabliert, hängt es nur noch von der Disziplin des Entwicklers ab, ob er jene Methode dann nicht auch noch gleich «anpasst». Das «mal eben etwas nachschauen» wird somit sehr leicht zum «mal eben etwas ändern». Solch ungeplante Spontanänderungen leisten der Architekturerosion aber Vorschub, indem sie Codebestandteile verbinden, die eigentlich entkoppelt sein sollten, was in der Praxis meist durch ein Umgehen der Schichtentrennung wahrgenommen werden kann. Sie sorgen ausserdem für Bugs, da der Entwickler nicht immer wissen kann, in welchem Kontext der von ihm geänderte Code noch verwendet wird, und sie machen den Code insgesamt schwerer verständlich und lösen schnell eine Kaskade weiterer ungeplanter Änderungen aus.
Zugegeben, dies klingt, als würde der Autor versuchen, ein Horrorszenario zu konstruieren. Aber gerade in sehr lang laufenden Projekten, mit sehr grosser Codebasis, ohne Code-Reviews und statischer Codeanalyse, ergibt sich immer das gleiche Bild. Häufig kommt es zu einer Wucherung innerhalb des Quellcodes, die nachträglich nur sehr schwer zu beheben ist. Als Ergebnis kann die Codebasis dann nicht mehr aufgetrennt werden, weil die verschiedenen Bestandteile so stark miteinander verbunden sind, dass sie nur noch als Ganzes funktionieren. Trennschichten haben sich damit also aufgelöst, und Schnittstellen sind nur noch Makulatur. Der ganze Prozess verläuft dabei so schleichend, dass er erst wahrgenommen wird, wenn es schon zu spät ist (vgl. Kasten Architekturerosion).
Um nun aber keinen falschen Eindruck zu erwecken: Ein Mono-Repo ist nicht zwangsläufig ein Anti-Pattern. Zum Code-Monolithen wird es, weil es unzureichende organisatorische und technische Sicherungsmechanismen gibt, um besagten Wildwuchs zu verhindern.

Warum macht man so was (nicht)?

Es stellt sich also die Frage, warum man nicht von Beginn an die Software entsprechend aufteilt und wartbar gestaltet. Bei neuer Software kann und sollte man dies auch tun. Bei bestehender Software hat dies meist den einfachen Grund, dass natürlich gewachsene Software nun einmal genau so entsteht. Mit «natürlich gewachsen» ist hierbei gemeint, dass die Software ohne grössere Anpassungen der Gesamtarchitektur immer weiterentwickelt wird und die Architekturerosion somit ungehindert fortschreiten kann. Man beginnt mit einem kleinen Programm, das bestimmte Aufgaben erfüllt, und diese Aufgabenmenge steigt über die Jahre hinweg, womit die internen Strukturen des Softwaresystems selbst auch immer komplexer werden. Hierbei nachträglich eigenständige Module oder Komponenten herauszulösen, diese separiert bereitzustellen und zu pflegen ist mit einem erheblichen Restrukturierungsaufwand verbunden, der den Stakeholdern meist nur schwer vermittelt werden kann.
Die Nachteile von Monolithen liegen also auf der Hand: Sie können nur beschränkt skaliert werden und verleiten zu schwer wartbaren Strukturen. Somit wundert man sich nicht, dass eine Alternative, die all diese Nachteile adressiert, auf so offene Ohren gestossen ist wie Microservices.
Verwandte Themen