Abstraktionsgrenzen
Architektur besteht nicht aus Diagrammen.
Sie besteht aus Grenzen.
Abstraktionsgrenzen definieren:
- Was gehört zusammen?
- Was darf voneinander wissen?
- Wo endet Verantwortung?
- Wo beginnt Kopplung?
Falsch gezogene Grenzen erzeugen:
- hohe Änderungsrisiken
- versteckte Abhängigkeiten
- Testprobleme
- fragile Systeme
- politische Reibung zwischen Teams
Gute Systeme sind nicht nur modular.
Sie sind sinnvoll geschnitten.
1. Was ist eine Abstraktionsgrenze?
Eine Abstraktionsgrenze trennt:
- Verantwortung
- Wissen
- Abhängigkeiten
- Änderungsgründe
Beispiele:
- UI ↔ Domäne
- Domäne ↔ Infrastruktur
- Service A ↔ Service B
- Team A ↔ Team B
Eine Grenze ist dann gut, wenn Änderungen auf einer Seite nicht ungewollt die andere destabilisieren.
2. Warum Abstraktionsgrenzen entscheidend sind
Software ändert sich ständig.
Wenn eine kleine fachliche Änderung:
- mehrere Module betrifft
- Tests überall brechen lässt
- Teams synchronisieren muss
- Deployments koppelt
dann sind die Grenzen falsch.
Abstraktionsgrenzen sind Risikominimierung.
3. Gute vs. schlechte Grenzen
Gute Grenzen
- Klare Verantwortlichkeit
- Wenige, stabile Schnittstellen
- Geringe Wissensübertragung
- Isolierte Tests möglich
- Änderungen bleiben lokal
Schlechte Grenzen
- Zirkuläre Abhängigkeiten
- „Shared Utilities“-Wildwuchs
- Cross-Cutting ohne Kontrolle
- Implizite Seiteneffekte
- Gemeinsame Datenmodelle ohne Ownership
4. Abstraktion ≠ Komplexität
Eine Abstraktion ist nur sinnvoll, wenn sie:
- Komplexität reduziert
- Stabilität erhöht
- Änderungsrisiko minimiert
Zu viele Abstraktionen führen zu:
- unnötiger Indirektion
- schwer lesbarem Code
- künstlicher Architektur
YAGNI gilt auch für Abstraktion.
5. Typische Fehlmuster
❌ Framework-Leakage
Domänenlogik kennt:
- HTTP
- ORM
- Angular/React
- Datenbankdetails
Folge:
Framework-Wechsel wird zum Großprojekt.
❌ Geteiltes Datenmodell
Mehrere Services teilen dasselbe Schema.
Folge:
Jede Änderung ist ein Koordinationsprojekt.
❌ Cross-Service-Domänenlogik
Business-Logik verteilt sich über mehrere Services.
Folge:
Fehlerursachen sind schwer lokalisierbar.
❌ „Shared“-Module ohne Ownership
Ein gemeinsames Modul wächst unkontrolliert.
Folge:
Alle hängen davon ab, niemand verantwortet es.
6. Abstraktionsgrenzen und Teamstruktur
Abstraktionsgrenzen sollten Teamgrenzen widerspiegeln.
Wenn zwei Teams ständig synchronisieren müssen, ist die Grenze falsch.
Conway’s Law wirkt hier direkt.
Teamgrenzen ohne technische Grenzen erzeugen Reibung.
Technische Grenzen ohne Teamverantwortung erzeugen Chaos.
7. Abstraktionsgrenzen im Kontext von Microservices
Microservices lösen keine Strukturprobleme.
Wenn Abstraktionsgrenzen im Monolithen schlecht waren, werden sie im Microservice nur verteilter.
Ein Service ist nur dann sinnvoll, wenn:
- er eine klare Domäne kapselt
- er eigenständig deploybar ist
- er nicht permanent synchronisiert werden muss
Microservices sind Organisationsentscheidungen.
8. Abstraktionsgrenzen und Testbarkeit
Gut gezogene Grenzen ermöglichen:
- isolierte Unit Tests
- klar definierte Integrationspunkte
- reproduzierbare E2E-Flows
Wenn Tests nur über E2E möglich sind, ist die interne Abstraktion meist schwach.
9. Leitfragen für gute Grenzen
- Hat diese Einheit einen klaren Änderungsgrund?
- Kann ich sie isoliert testen?
- Wissen Module zu viel voneinander?
- Erfordert eine Änderung Koordination mit mehreren Teams?
- Ist die Schnittstelle stabil oder ständig in Bewegung?
Wenn mehrere Antworten problematisch sind, liegt ein Schnittproblem vor.
10. Abstraktionsgrenzen sind Entscheidungen
Grenzen entstehen nicht zufällig.
Sie sind:
- Architekturentscheidungen
- Organisationsentscheidungen
- Risikoentscheidungen
Ohne bewusste Grenzziehung entsteht implizite Kopplung.
Kerngedanke
Architektur ist die Kunst, gute Grenzen zu ziehen.
Nicht zu viele.
Nicht zu wenige.
Sondern solche, die Veränderung bezahlbar machen.
Gute Abstraktionsgrenzen reduzieren:
- technische Schulden
- Kommunikationskosten
- Fehlerausbreitung
- organisatorische Reibung
Schlechte Grenzen skalieren Probleme.
Und Probleme skalieren schneller als Features.