Warum "zukunftssichere" Architekturen gefährlich sind
Die Frage "Ist diese Software-Architektur zukunftssicher?" kann man eigentlich generell mit "nein" beantworten. Schlimmer noch: Die Frage zu stellen, kann schon auf ein falsches Verständnis von Architektur hinweisen.
- Eberhard Wolff
Die Frage "Ist diese Software-Architektur zukunftssicher?" kann man eigentlich generell mit "nein" beantworten. Schlimmer noch: Die Frage zu stellen, kann schon auf ein falsches Verständnis von Architektur hinweisen.
Die Softwarearchitektur eines IT-Systems umfasst zwei Bereiche: Die Technologien zur Umsetzung und die Strukturierung des Systems in einzelne Module. Geht es um die Zukunftssicherheit von Architekturen, muss man beide Bereiche betrachten.
Struktur
Eine grobgranulare Struktur eines Systems ist notwendig, damit Menschen das System verstehen und ändern können. Softwaresysteme werden im Team entwickelt. Das führt zu einem Problem: Kein Mensch kann die Arbeit aller Menschen aus dem Team im Detail verstehen. Eine Strukturierung des Systems in Module ermöglicht ein Verständnis auf einer abstrakten Ebene - der Ebene der Module und nicht auf der Ebene einzelner Codezeilen.
Die architekturelle Struktur sollte die Module des Systems so anordnen, dass Funktionalitäten leicht zu ändern und zu verstehen sind. Also hängt die Struktur von den Funktionalitäten und damit von den Anforderungen ab. Das zentrale Problem bei der Softwareentwicklung ist, dass sich Anforderungen ändern – nicht nur weil Kunden neue Anforderungen stellen, sondern auch, weil beim Durchdenken oder bei der Anwendung des Systems Anforderungen klarer werden, sich neue Möglichkeiten offenbaren oder Inkonsistenzen auftauchen und beseitigt werden müssen. Teams, Kundinnen und Anwender lernen ständig mehr über das System und die zu entwickelnde Funktionalität. Dieses neue Wissen zu ignorieren,wäre absurd. Daher ergeben sich zwangsläufig Änderungen.
Einige Änderungen an den Anforderungen sind so signifikant, dass die Strukturierung des Systems und damit die Architektur angepasst werden muss. Ob das System zukunftssicher ist, entzieht sich also prinzipiell unserer Kenntnis, weil wir die Zukunft und die neuen Anforderungen nicht absehen können. Vielleicht passt die Architektur gut zu den neuen Anforderungen, vielleicht sind aber auch größere Änderungen notwendig.
Nur Absehbare Ă„nderungen einbeziehen
Aber nicht alle neuen Anforderungen sind vollkommen überraschend. Natürlich ist es sinnvoll, absehbare Änderungen in den Entwurf der Architektur einzubeziehen. Wenn die Änderungen dann doch nicht erfolgen, ist die Architektur an einigen Stellen unnötig flexibel und daher möglicherweise an einigen Stellen zu kompliziert. Das ist aber ein weiterer Trade-off in der Architektur. Soll das System auf absehbare Änderungen vorbereitet werden oder nicht? Über solche Fragen nachzudenken und sie individuell zu entscheiden, ist sicher besser, als sie blind mit "You Ain't Gonna Need It" (YAGNI, Du wirst es nicht brauchen) zu beantworten. Dieses Motto stammt aus dem Extreme-Programming-Umfeld der Jahrtausendwende. Es diente dazu, sich gegen übermäßig generische Lösungen abzusetzen. Wenn man nämlich ein System so entwickelt, dass es auf alle denkbaren Änderungen vorbereitet ist, wird es übermäßig komplex. Daher sollte die Architektur nur absehbare Änderungen in Erwägung ziehen und diese auch nur dann in den Architektur einfließen lassen, wenn die Vorteile klar überwiegen.
Zukunftsfähigkeit = einfach verständlich
Dennoch kann man in der Strukturierung eine gewissen Zukunftsfähigkeit des Systems erreichen. Wenn die Strukturierung das Verständnis nicht erleichtert oder wenn Module nicht lose gekoppelt sind und Änderungen dadurch immer größere Teile des System betreffen, dann ist das System schon jetzt nicht einfach wartbar. Das wird sich in Zukunft nicht verbessern.
Wenn zentrale Konzepte der Fachdomäne gar nicht im System abgebildet sind oder fachliche Konzepte generell im System schlecht repräsentiert sind, ist es schwierig die Abbildung der Fachlichkeit auf das System zu verstehen. Verständnis ist aber die Voraussetzung für jede Änderung.
Also kann man die Struktur des Systems möglichst eng an der Fachlichkeit ausrichten und so zukunftsfähig gestalten. Wenn die fachlichen Konzept klar und verständlich umgesetzt sind, kann man sie auch einfach ändern und auf zukünftige Anforderungen anpassen. Über die fachlichen Konzepte hinaus eingebaute Flexibilität schadet dabei mehr als sie hilft: Sie ist meistens an den falschen Stellen und verschlechtert damit die Verständlichkeit. Man kann eben zukünftige Änderungen nicht vorweg erahnen und einfach implementierbar machen.
Technologie
Neben der Struktur ist auch die Technologieauswahl ein wichtiger Teil der Architektur. Softwareentwicklung unterliegt einem ständigen Technologiewandel. Man kann einem Technologie-Stack dennoch bescheinigen, dass er mehr oder weniger modern ist. Diese Aussage weist schon auf mangelnde Zukunftssicherheit hin: Was heute modern ist, ist morgen veraltet. “Modern” ist zunächst ein relativ inhaltsleerer Begriff: Was nützt es, wenn eine Technologie erst einige Jahre alt ist?
Die Modernität von Technologien darf kein Selbstzweck sein: Schließlich sollen Softwarearchitekturen Geschäftsprobleme lösen – und dazu ist ein möglichst moderner Technologie-Stack nicht zwingend notwendig. Aufwand, der in die Modernisierung von Technologien und das Erlernen neuer Ansätze fließt, sollte vielleicht besser in Aktivitäten fließen, die Geschäftswert erzeugen. Aber irgendwann sind Technologien so alt, dass sie nicht mehr weiter gepflegt werden. Spätestens wenn dann Sicherheitsupdates ausbleiben, muss man aktualisieren oder umsteigen. Sonst kann ein Sicherheitsproblem dazu führen, dass das System nicht mehr nutzbar ist oder gar erheblichen Schaden anrichtet. In beiden Fällen erzeugt das System keinen Geschäftswert mehr, sondern im Extremfall einen Geschäftsverlust. Wenn irgendwann die Technologien so alt sind, dass sich niemand mehr damit beschäftigen will, nimmt der Druck für eine Migration weiter zu.
Es kann natürlich Technologien geben, die scheinbar zukunftssicher sind. Die Programmiersprache Java beispielsweise gibt es seit über 25 Jahren. Aber auch hier gilt: Alte Java-Versionen bekommen keine Sicherheitsupdates mehr. Und Java-Code aus dem letzten Jahrhundert sieht wegen neuer Sprach-Features anders aus als aktueller Code. Schließlich gibt es ganz andere Frameworks oder zumindest neue Versionen der Frameworks. Selbst eine Technologie, die lange existiert, ist also einem Wandel unterworfen und muss ständig aktualisiert werden.
Anders gesagt: Man kommt nicht darum herum, neue Technologien einzusetzen. Der Wunsch nach einer Zukunftssicherheit ist nicht realisierbar.
Container
Container können die Zukunftssicherheit erhöhen: Jeder Container enthält ein eigenes Dateisystem und ist von anderen Containern weitgehend isoliert. Aus Sicht der Software wirkt es fast so, als wäre jeder Container ein getrennter Computer mit einem eigenen Dateisystem, einer eigener Netzwerkschnittstelle usw. Daher können in jedem Container eine eigene Programmiersprache und eigene Frameworks eingesetzt werden. Wenn man beispielsweise mit Microservices die Teile des Systems auf mehrere Container verteilt, kann ein Update auf eine neue Technologie zunächst in einem Container und dann schrittweise in anderen Containern umgesetzt werden. Das ist risikoärmer und macht die Architektur zukunftssicherer, weil die Einführung neuer Technologien einfacher wird.
Container-Technologien sind aber auch irgendwann erfunden worden: Kubernetes gibt es seit 2014, Docker seit 2013. Bis die Technologien im Mainstream angekommen sind, hat es dann noch einige Jahre gedauert. Um sie zu nutzen, muss man ältere Projekte ändern. Diese Innovationen sind nicht vorhersehbar. 2012 kann kein Architektur-Review vorhergesehen haben, dass ein Projekt nicht zukunftssicher ist, weil es keine Container nutzt.
Und eines ist auch bei Containern sicher: Es wird eine Zeit geben, in der man die Nase rĂĽmpft, wenn jemand noch Container nutzt, weil es dann eine viel bessere, neue Technologie geben wird.
Hinzu kommt: In einem Frontend mehrere JavaScript-Frameworks gemeinsam zu nutzen bleibt eine echte Herausforderung – aber die Geschwindigkeit, mit der neue JavaScript-Frameworks erscheinen, ist nach wie vor beeindruckend. Also sind diese Probleme gerade da schwer lösbar, wo neue Technologien noch mit einer viel größeren Geschwindigkeit erscheinen.
Man sollte sich also an den Gedanken gewöhnen, dass man im Moment an Lösungen arbeitet, die irgendwann technologisch veraltet sind. Und man kann das Problem höchstens abmildern, aber nicht lösen.
Also Zukunftssicherheit vermeiden!
Die Frage nach der Zukunftssicherheit kann sogar ein Hinweis auf ein Problem sein: Wenn eine Architektur zukunftssicher wäre, müsste man sie nicht korrigieren. Das ist aber wünschenswert. Wenn Korrekturen stattdessen als Schwäche einer Architektur interpretiert und daher möglichst wenige zum Ziel werden, kann ein Problem sein. Dann können Hinweise auf eigentlich notwendige Änderungen ignoriert werden, um keine Korrekturen an der Architektur vornehmen zu müssen. Wer will schon gerne eingestehen, dass die Architektur eben nicht zukunftssicher war? Durch das Unterdrücken der Änderungen erscheint die Architektur "zukunftssicher", aber in Wirklichkeit passt die Architektur zunehmend schlechter zum System. Dass Architekturen nicht rechtzeitig an Änderungen angepasst werden, ist vermutlich eine größere Quelle für schlechte Architekturen als Probleme mit dem ursprünglichen Entwurf. So führt der Wunsch nach einer zukunftssicheren Architektur zu einer schlechteren Architektur.
Aber diese Paradoxie muss nicht der einzige Grund für ausbleibende Änderungen an der Architektur sein. Eine Architektur zu ändern ist anstrengend: Schließlich hat man sich mit dem Entwurf viel Mühe gegeben und vielleicht wesentliche Konzepte sogar schon in Prototypen ausprobiert. Von diesen ganzen Mühen Abschied zu nehmen, kann schwer fallen, ist aber manchmal nötig. Und man sollte auch kein schlechtes Gewissen haben, weil die Architektur nun obsolet ist. Softwareentwicklung ist nur in Iterationen umsetzbar. Eine Iteration der Architektur trägt die nächste schon in sich. Dennoch muss man sich bei dem Entwurf der Architektur Mühe geben. Erst wenn man wirklich versucht, die Architektur zu entwerfen, werden sich die Optimierungspotentiale zeigen.
Wenn es notwendig ist, Architekturen ändern zu können, kann die Erstellung der Architektur keine Phase in einem Projekt sein, die irgendwann abgeschlossen ist. Schließlich muss die Architektur ständig an die sich ändernde Welt angepasst werden. Dazu sollte es einen Prozess geben. Wenn es nämlich keinen Prozess für Änderungen an der Architektur gibt, wird sie vermutlich nicht angepasst werden. Dann lassen sich die Funktionalitäten zunehmend schlechter umsetzen.
Fazit
Die Frage nach einem Architekturänderungsprozess ist also wichtiger als die Frage nach der Zukunftssicherheit der Architektur. Und Projekte, die auf diese Frage keine Antwort haben, setzen sich der Gefahr aus, in Zukunft Schwierigkeiten mit der Architektur zu haben.
tl;dr
Technologische Innovationen und neue Anforderungen machen Änderungen an der Architektur zwingend - sie kann nicht zukunftssicher sein. Lösung: Dieser Realität in die Augen sehen und Architekturen anpassen, wenn notwendig.
Vielen Dank an Gerrit Beine, Martin Eigenbrodt, Joachim Praetorius und Gernot Starke fĂĽr die Kommentare zu einer frĂĽheren Version des Artikels. ()