Softwarearchitektur ohne Grundsätze!

Continuous Architecture  –  16 Kommentare

In der Softwarearchitektur gibt es traditionelle Grundsätze, die oft zu Problemen führen. Sich dieser Herausforderungen klar zu werden, ist der erste Schritt, um sie zu beseitigen oder sogar von Anfang an zu vermeiden.

Uns sind jahrelang Architekturgrundsätze eingehämmert worden, die viele Projekte auch umgesetzt haben. Daher liegen mittlerweile Erkenntnisse darüber vor, ob diese Grundsätze wirklich hilfreich sind. Die Ideen sind auf den ersten Blick sinnvoll und man hat sich an sie gewöhnt, obwohl sie sich nicht bewährt haben. Über Misserfolge spricht man eben nicht so gerne.

Einige Beispiele:

  • Viele Projekte haben das Ziel, die Wiederverwendung von Komponenten zu ermöglichen. Ich treffe aber praktisch nie auf Projekte, die von Wiederverwendung profitieren. Also ist dieses Ziel kaum erreichbar. Außerdem hat Wiederverwendung auch Nachteile, wie ein früherer Blogbeitrag aufzeigt. Weil aber Wiederverwendung so ein typisches Ziel ist, fällt es schwer, sich davon zu verabschieden.
  • Daten sollten idealerweise redundanzfrei gespeichert werden. Außerdem hat Objektorientierung uns objektorientierte Modelle gelehrt. Also wird die Domäne in einem einzigen und damit redundanzfreien objektorientierten Modell mit Persistenz in der Datenbank modelliert. Solche Modelle sind oft extrem komplex und haben Hunderte von Tabellen oder Spalten in der Datenbank. Die Lösung ist Bounded Context aus dem Domain-driven Design: Statt eines Modells nutzt das System mehrere, spezialisierte Modelle. Oft sind diese Modelle auch redundanzfrei: Das Modell für eine Bestellung im Kontext "Bezahlung" hat ganz andere Daten als jenes im Kontext "Lieferung".
  • Letztlich werden bei Architekturen oft schweigend bestimmte Ziele vorausgesetzt. Ein Beispiel ist Skalierbarkeit. Das ist ja auch logisch: Eine gute Architektur muss Skalierbarkeit bieten. Ein System, das nicht skaliert, kann ein erhebliches Problem sein. Auf der anderen Seite ist Skalierbarkeit eigentlich ein Luxusproblem, denn es bedeutet, dass ein System schon erfolgreich ist und nun ausgebaut werden muss. Also sollte man die realen Anforderungen an die Architektur ermitteln, bevor man irgendwelche Annahmen trifft. Wenn ein System aus Compliance-Gründen oder wegen Sicherheit gar nicht in Produktion geht, nützt die Skalierbarkeit nichts. Auch dazu gab es bereits einen Blogbeitrag. Natürlich gilt die erste Regel für Softwarearchitektur: Stell dich nicht dumm. Wenn Skalierbarkeit wirklich notwendig ist, dann sollte man sie auch umsetzen und man sollte natürlich auch keine Flaschenhälse einbauen.
  • Das Ziel der Technologieunabhängigkeit führt oft dazu, dass Abstraktionen und Indirektionen eingebaut werden, um von einer konkreten Implementierung unabhängig zu sein. Die sind oft beschränkt, weil sie den kleinste gemeinsame Nenner aller möglichen Implementierungen umsetzen müssen. Oft scheint an einem gewissen Punkt außerdem doch die konkrete Implementierung durch, sodass eine echte Unabhängigkeit gar nicht erreicht wird. Und schließlich zahlt sich die Technologieunabhängigkeit erst aus, wenn tatsächlich eine neue Technologie genutzt werden soll. Bis dahin muss man aber mit der erhöhten Komplexität "bezahlen". Das muss nicht unbedingt am Ende der einfachere Weg sein. Oft ist es besser, technologieabhängig zu implementieren und die Technologie voll zu nutzen. Erst wenn eine andere Technologie genutzt werden soll, baut man das System um und bezahlt die Komplexitätskosten. Man kann die Komponenten klein halten, sodass sie recht einfach mit einer anderen Technologie implementiert werden können.
  • Ein weiteres Beispiel ist die Standardisierung und Vereinheitlichung. Sicher hat das einen Effizienzgewinn zur Folge, aber wenn man sich die IT-Landschaft eines Unternehmens anschaut oder auch nur die in einem Projekt verwendeten Bibliotheken, dann ergibt sich oft ein chaotisches Bild. Das ist sicher nicht optimal, aber es haben eben auch genügend Leute versucht, dieses Problem zu lösen und sind gescheitert. Man kann sich dort einreihen – oder sich darauf beschränken, nur bestimmte Aspekte wie den Betrieb zu standardisieren.

Vielen Dank an meine Kollegen Christoph Iserlohn, Lutz Hühnken, Christian Stettler, Stefan Tilkov und Benjamin Wolf für die Kommentare zu einer früheren Version des Artikels.

tl;dr

Damit Softwarearchitektur besser wird, müssen wir Abschied nehmen von dem, was nicht funktioniert. Das ist aber nicht so einfach, denn die Prinzipien sind mittlerweile eine Tradition – die es zu durchbrechen gilt.