BCE-Pattern im Monolith: Saubere Architektur für komplexe Systeme
Viele Unternehmen starten mit einem Monolithen, weil er zu Beginn einfach und schnell umzusetzen ist. Kurze Entwicklungszyklen, geringe Infrastrukturkomplexität und ein einfacher Deploy-Prozess machen ihn gerade in frühen Projektphasen attraktiv. Doch mit wachsender fachlicher Komplexität entstehen typische Herausforderungen:
- steigende Kopplung zwischen Komponenten
- unklare Verantwortlichkeiten
- schwer testbare Businesslogik
- sinkende Wartbarkeit
Die zentrale Frage lautet daher:
Wie bleibt ein Monolith langfristig wartbar, modular und zukunftssicher?
Das Boundary-Control-Entity (BCE)-Pattern bietet hier eine strukturierte Antwort. Es schafft klare Verantwortlichkeiten innerhalb eines Systems und ermöglicht es, auch große Monolithen kontrolliert wachsen zu lassen. Gleichzeitig erleichtert es die spätere Migration in Richtung Microservices erheblich.
Was ist das BCE-Pattern?
Das BCE-Pattern unterteilt die Softwarearchitektur in drei klar definierte Rollen:
-
Boundary Schnittstelle zur Außenwelt, z.B. REST-APIs, Messaging-Adapter oder externe Integrationen.
-
Control Orchestriert Use-Cases und steuert den Anwendungsfluss. Hier liegt die eigentliche Anwendungslogik.
-
Entity Repräsentiert fachliche Objekte und Geschäftsregeln – unabhängig von UI oder Infrastruktur.
Diese Trennung ist bewusst einfach gehalten, aber extrem wirkungsvoll. Sie sorgt dafür, dass jede Schicht eine klar definierte Aufgabe erfüllt und sich nicht mit anderen Verantwortlichkeiten vermischt.
Warum ist das wichtig?
In vielen realen Projekten verschwimmen die Grenzen zwischen Präsentation, Businesslogik und Datenhaltung. Das führt zu typischen Problemen:
- Controller enthalten Businesslogik
- Services greifen direkt auf fremde Domänen zu
- Entities kennen Infrastrukturdetails
- Tests werden komplex und instabil
Das BCE-Pattern wirkt diesen Problemen gezielt entgegen:
-
Klarheit Entwickler wissen sofort, wo welche Logik hingehört.
-
Testbarkeit Jede Schicht kann isoliert getestet werden.
-
Wartbarkeit Änderungen bleiben lokal und beeinflussen andere Bereiche nur minimal.
-
Erweiterbarkeit Neue Features lassen sich strukturiert integrieren.
Warum BCE im Monolith?
Ein Monolith ist nicht per se schlecht. Im Gegenteil: Ein gut strukturierter Monolith kann über viele Jahre hinweg effizient betrieben und weiterentwickelt werden.
Das Problem entsteht erst, wenn Struktur fehlt.
Das BCE-Pattern hilft dabei, genau diese Struktur herzustellen:
- klare Trennung fachlicher Domänen
- definierte Abhängigkeitsrichtungen
- reduzierte Kopplung
Jede Domäne organisiert sich intern selbst:
- eigene Boundaries für externe Kommunikation
- eigene Control-Klassen für Use-Cases
- eigene Entities als fachliches Modell
Dadurch entsteht ein sogenannter modularer Monolith.
Der entscheidende Vorteil:
Eine spätere Aufteilung in Microservices wird nicht erzwungen, sondern vorbereitet.
Domänen können bei Bedarf extrahiert werden, ohne das gesamte System neu denken zu müssen.
Unser Ansatz: Domänenbasierte Struktur
Wir strukturieren den Monolithen strikt nach fachlichen Domänen:
de.acmebank.person
de.acmebank.konto
de.acmebank.rechnung
de.acmebank.kredit
de.acmebank.buchungen
Jede Domäne weist die gleiche Struktur auf:
- Boundary → REST-APIs, Adapter, externe Schnittstellen
- Control → Use-Case-Logik und Orchestrierung
- Entity → fachliche Modelle und Regeln
- Repository → Persistenzzugriff
Diese Wiederholung ist bewusst gewählt: Sie schafft Orientierung und reduziert die kognitive Belastung im Team.
Architekturprinzip: Abhängigkeitsrichtung
Eine der wichtigsten Regeln im BCE-Pattern lautet:
Abhängigkeiten zeigen immer nach innen
Boundary → Control → Entity
Das bedeutet konkret:
- Boundary kennt Control
- Control kennt Entity
- Entity kennt nichts außerhalb der Domäne
Cross-Domain-Kommunikation erfolgt ausschließlich über Boundaries.
Das verhindert versteckte Kopplungen und sorgt für klare Schnittstellen.
Optimierte Architektur-Skizze
BCE im Detail
Boundary
Die Boundary-Schicht ist der Einstiegspunkt ins System.
Typische Aufgaben:
- Entgegennahme von Requests
- Validierung von Eingaben
- Mapping von DTOs auf Domain-Objekte
- Rückgabe von Responses
Wichtig: Keine Businesslogik!
Control
Die Control-Schicht bildet die Anwendungsebene.
Aufgaben:
- Implementierung von Use-Cases
- Orchestrierung von Abläufen
- Koordination mehrerer Entities
- Aufruf externer Boundaries
Hier liegt die eigentliche Intelligenz der Anwendung.
Entity
Entities bilden das fachliche Herz der Anwendung.
Eigenschaften:
- enthalten Geschäftsregeln
- sind unabhängig von Frameworks
- haben keine Infrastrukturabhängigkeiten
Ziel: ein stabiles, langlebiges Domainmodell.
Best Practices
Einige bewährte Regeln für den Einsatz von BCE:
-
Keine Businesslogik in der Boundary
-
Keine direkte Kopplung zwischen Domänen
-
Entities bleiben frei von technischen Abhängigkeiten
-
Use-Cases klar modellieren
-
Abhängigkeiten strikt einhalten
-
Kommunikation über Boundaries erzwingen
Diese Regeln wirken simpel, entfalten aber in großen Systemen enorme Wirkung.
Beispiel mit Spring Boot
// Boundary
@RestController
@RequestMapping("/api/konto")
public class KontoApi {
private final KontoService kontoService;
public KontoApi(KontoService kontoService) {
this.kontoService = kontoService;
}
@PostMapping
public ResponseEntity<KontoDto> create(@RequestBody KontoDto dto) {
Konto konto = kontoService.create(dto.getNummer(), dto.getSaldo());
return ResponseEntity.ok(KontoMapper.toDto(konto));
}
}
// Control
@Service
public class KontoService {
private final KontoRepository kontoRepository;
public KontoService(KontoRepository kontoRepository) {
this.kontoRepository = kontoRepository;
}
public Konto create(String nummer, BigDecimal saldo) {
Konto konto = new Konto(nummer, saldo);
konto.validate();
return kontoRepository.save(konto);
}
}
// Entity
public class Konto {
private final String nummer;
private BigDecimal saldo;
public Konto(String nummer, BigDecimal saldo) {
this.nummer = nummer;
this.saldo = saldo;
}
public void validate() {
if (saldo.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException("Saldo darf nicht negativ sein");
}
}
}
Fazit
Das BCE-Pattern ist ein einfaches, aber äußerst wirkungsvolles Mittel, um komplexe Systeme zu strukturieren.
Es hilft dabei:
- Monolithen wartbar zu halten
- fachliche Grenzen sichtbar zu machen
- Komplexität zu reduzieren
- Migrationen vorzubereiten
Der wichtigste Punkt:
BCE macht deinen Monolithen nicht kleiner – aber strukturiert ihn so, dass er langfristig skalierbar bleibt.