Zur Architektur

Komplexität muss sich rechtfertigen

Architektur soll zum tatsächlichen Problem passen - und die ehrliche Version dieses Satzes heißt: die meisten Projekte brauchen weniger Architektur, als sie bekommen.

Jede technische Entscheidung bringt Folgekosten mit sich. Frameworks müssen aktualisiert werden, Build-Pipelines können ausfallen, Abhängigkeiten bringen neue Sicherheitsrisiken mit und Abstraktionen funktionieren nie in jedem Fall so sauber wie geplant. Das spricht nicht gegen anspruchsvolle Werkzeuge. Es bedeutet nur, dass zusätzliche Komplexität auch dauerhaft gepflegt werden muss.

Trotzdem wird sie oft nicht bewusst gewählt. Eine einfache Marketing-Website startet dann mit einem serverseitigen Framework, einer Bibliothek für State Management und einer vollständigen CI-Pipeline - noch bevor jemand gefragt hat, wie häufig sich die Inhalte überhaupt ändern werden. Die technische Grundlage entsteht nicht aus dem tatsächlichen Bedarf, sondern wird aus dem letzten Projekt oder dem gerade aktuellen Architekturtrend übernommen.

Das Ergebnis sind Systeme, die aufwendig zu verändern sind und deshalb paradoxerweise nur selten verändert werden.

Ich versuche deshalb, mit der einfachsten Architektur zu beginnen, die ein Projekt zuverlässig tragen kann. Jede zusätzliche Schicht sollte ein konkretes Problem lösen, das heute tatsächlich existiert - nicht eines, das vielleicht irgendwann auftreten könnte. Und schon gar keines, das vor allem im Lebenslauf gut aussieht.

Diese Website ist dafür das einfachste Beispiel. Das Portfolio besteht aus HTML5, CSS und Vanilla JavaScript. Es gibt kein Framework, keinen Build-Prozess und kein Backend. Jede Datei lässt sich direkt öffnen, bearbeiten und anschließend im Browser neu laden. Das Deployment besteht im Wesentlichen daraus, Dateien bereitzustellen.

Natürlich könnte die Seite auch mit Next.js gebaut sein. Die wichtigere Frage lautet aber: Was würde dadurch besser?

Die Inhalte ändern sich einige Male im Monat. Die Interaktion beschränkt sich auf die Navigation und einige dezente Effekte beim Scrollen. Ein Framework würde ein node_modules-Verzeichnis, zusätzliche Konfiguration und regelmäßige Abhängigkeitsupdates mitbringen - im Gegenzug für Funktionen, die diese Website nicht benötigt. Für eine statische Publikation wäre React deshalb keine Verbesserung, sondern zusätzlicher Aufwand.

Das ist keine Kritik an React. Es ist eine Kritik daran, eine technische Entscheidung zu treffen, bevor das Problem überhaupt beschrieben wurde.

Die bewusste Begrenzung hatte außerdem einen Effekt, mit dem ich nicht vollständig gerechnet hatte: Sie erzwingt Klarheit. Ohne Komponentenbibliothek muss man selbst entscheiden, wie Typografie, Abstände und Hierarchie funktionieren. Ohne Build-Prozess gibt es weniger technische Schichten, hinter denen sich ein Fehler verstecken kann. Man arbeitet näher an der eigentlichen Sache.

Bei den kommerziellen Entscheidungsgrundlagen war dieselbe Frage deutlich folgenreicher. Das Unternehmen brauchte eine verlässliche Margen- und Preisanalyse auf Basis echter Einkaufsdokumente sowie eine Umsatz- und Cashflow-Prognose.

Eine naheliegende Lösung wäre ein Paket aus mehreren SaaS-Produkten gewesen: eines für die Dokumentenerkennung, eines für BI-Dashboards und ein weiteres für Prognosen. Danach hätte man diese Werkzeuge dauerhaft miteinander verbinden und dafür sorgen müssen, dass ihre Daten und Annahmen weiterhin zusammenpassen.

Stattdessen entstanden zwei kleine, lokal betriebene Anwendungen.

Margin & Pricing Intelligence verarbeitet rund 1.000 echte PDF-Rechnungen in 74 Sekunden und macht sichtbar, was das Unternehmen für seine Produkte tatsächlich bezahlt und welche Marge daraus entsteht.

Revenue & Cash-Flow Intelligence unterstützt Umsatzplanung, saisonale Erwartungen und Szenarioanalysen. Über das gesamte Jahr lag die Prognose nur 2,1 Prozent vom später tatsächlich erzielten Nettoumsatz entfernt. Hätte mir jemand dieses Ergebnis vorab versprochen, wäre ich wahrscheinlich skeptisch gewesen.

Nach klassischen Engineering-Maßstäben sind das keine spektakulären Anwendungen. Ihr Wert liegt darin, wie genau sie zum Problem passen. Beide erledigen eine klar definierte Aufgabe mit Daten, die dem Unternehmen gehören. Es gibt keine Gebühren pro Benutzer, keine Feature-Wünsche im Backlog eines externen Anbieters und keinen mühsamen Export der eigenen Daten aus einem fremden System. Der größere Zusammenhang ist unter Commercial Intelligence beschrieben.

Das bedeutet nicht, dass interne Anwendungen immer die richtige Antwort sind. Auch sie haben Schwächen. Sie können zu stark von den Menschen abhängen, die sie entwickelt haben, und mit der Zeit unbemerkt zu schwer wartbaren Altsystemen werden.

Die Entscheidung lautet deshalb nicht grundsätzlich „selbst bauen“ oder „Software mieten“. Beide Optionen sollten denselben Nachweis erbringen müssen: Warum passt diese Lösung besser zum tatsächlichen Problem?

Manchmal rechtfertigt das Problem durchaus eine anspruchsvollere Architektur. Google Performance Intelligence verwendet MCP mit OAuth, mehrere spezialisierte Agenten und einen Orchestrierungsagenten. Das ist deutlich mehr Architektur als bei den meisten anderen Systemen, die ich betreibe.

In diesem Fall hat jedoch jede zusätzliche Schicht eine klare Aufgabe. Die Agenten benötigen authentifizierten und begrenzten Zugriff auf drei unterschiedliche Google-Plattformen. Die Orchestrierung ist erforderlich, weil der eigentliche Nutzen erst aus der gemeinsamen Analyse mehrerer Datenquellen entsteht. Das Berechtigungsmodell ist wichtig, weil es eindeutig festlegt, was ein Agent selbstständig tun darf - und was nicht.

Genauso wichtig sind die Fälle, in denen ich mich bewusst gegen eine solche Architektur entschieden habe. Mehrere benachbarte Abläufe hätten technisch an dieselbe Orchestrierung angeschlossen werden können. Einige davon ließen sich jedoch bereits zuverlässig mit einem geplanten Skript und einer Tabelle lösen. Eine zusätzliche Integration hätte dort keinen echten Nutzen geschaffen. Sie wäre Architektur auf der Suche nach einem Problem gewesen.

Technische Zurückhaltung zeigt sich nicht darin, dass anspruchsvolle Möglichkeiten fehlen. Sie zeigt sich darin, dass man auf sie verzichtet, obwohl sie verfügbar und interessant wären.

Vor jeder zusätzlichen Schicht versuche ich deshalb, eine einfache Frage zu beantworten:

Welches konkrete Problem löst sie, das die einfachere Variante nicht lösen kann?

„Wir brauchen Skalierbarkeit“ ist noch kein konkretes Problem.

„Wir verarbeiten tausend Rechnungen, und der aktuelle Ablauf dauert elf Minuten“ ist eines.

Wenn sich die Antwort nur vage formulieren lässt, ist wahrscheinlich auch der Bedarf noch vage. Dann wird zusätzliche Architektur schnell zu technischen Schulden, die lediglich besser verkauft werden.

Komplexität sollte aus dem Problem entstehen - nicht aus dem Werkzeug, das man gerade verwenden möchte.

Das ist kein Plädoyer für primitive Systeme. Es ist ein Plädoyer für angemessene Systeme: Architektur, deren Anspruch sich erklären lässt, indem man auf das Problem zeigt und nicht auf das verwendete Ökosystem.

Die besten Architekturen, die ich umgesetzt habe, waren für ihre Nutzer meist nahezu unsichtbar. Die schlechtesten sahen auf einem Diagramm oft besonders beeindruckend aus.