Enterprise Java als echtes Lesebuch.
Diese Fassung ersetzt die kachelartige Lehrbuchansicht durch ein ruhiges Buchlayout: klare Teile, feste Sidebar, lesbare Kapitel, Diagramme, Codeblöcke im JetBrains-Dark-Stil und eine bessere Öffnungsreihenfolge.
Wie du dieses Buch lesen solltest
Beginne mit Teil 1 bis Teil 3. Dort entstehen Grundverständnis, Framework-Vergleich und Praxisarchitektur.
Teil 4 und Teil 5 sind für Senior-Themen: Konsistenz, Betriebsreife, Governance, Performance und Migration.
Teil 6 enthält Labs und Refactoring-Workshops. Danach ist das Maven-Capstone-Projekt sinnvoll.
Teil 7 bündelt Entscheidungsbäume, Interviewfragen, Produktionschecklisten und Abschluss.
Markdown bleibt als Quelle im Paket erhalten. Die Lesefassung verlinkt aber HTML-first, damit lokale Browser-Navigation sauber bleibt.
Grundlagen & Enterprise-Denken
Java Enterprise als Gesamtbild: Sprache, Build, Plattform, Persistenz, Integration und Betrieb.
Kapitel 001 · Teil 1Grundbild Enterprise JavaWarum Enterprise Java mehr ist als eine Sammlung von Frameworks.
Was Enterprise Java bedeutet
Enterprise Java ist die Fähigkeit, fachliche Abläufe, technische Laufzeitumgebungen, Datenhaltung, Integration, Sicherheit, Betrieb und Änderbarkeit gemeinsam zu beherrschen. Ein Senior-Entwickler denkt nicht nur in Klassen, sondern in Verträgen, Grenzen, Lebenszyklen, Fehlerszenarien und betrieblichen Nachweisen.
| Ebene | Typische Bausteine | Worauf du achten musst |
|---|---|---|
| Fachlichkeit | Order, Customer, Invoice, Payment, Contract | Begriffe stabilisieren, Invarianten schützen, Use Cases klar schneiden |
| Anwendung | REST, SOAP, Events, Batch, UI | Input validieren, Fehlerverträge, Idempotenz und Transaktionen definieren |
| Persistenz | JPA/Hibernate, JDBC, Migrationen | Aggregatgrenzen, Fetching, Locking, Konsistenz und Performance |
| Integration | Kafka, JMS, REST Clients, SOAP Clients | Schema-Versionierung, Retry, Timeout, DLQ, Kompatibilität |
| Betrieb | Container, Kubernetes/OpenShift, Observability, Security | Health Checks, Ressourcen, Logs, Traces, Secrets und SLAs |
Fachliche und technische Sicht trennen
Eine typische Fehlerquelle in Enterprise-Projekten ist, dass technische Begriffe die fachlichen Begriffe verdrängen. Dann spricht das Team nur noch über Controller, Repository und Entity, aber nicht mehr über Bestellung, Zahlung, Rechnung, Storno oder Lieferfreigabe. Gute Enterprise-Architektur beginnt mit einem fachlichen Modell und bildet dieses Modell technisch kontrolliert ab.
Fachliche Sicht
Was passiert im Unternehmen? Welche Entscheidung wird getroffen? Welcher Zustand ändert sich?
Technische Sicht
Welche Schnittstelle nimmt die Anfrage an? Welche Transaktion läuft? Welche Daten werden gespeichert?
Betriebliche Sicht
Wie erkennt man Fehler? Wie wird skaliert? Was passiert bei Ausfall von DB, Broker oder Partner-API?
Typischer Enterprise-Request
Ein einzelner HTTP-Request wirkt einfach, enthält aber viele implizite Entscheidungen: Authentifizierung, Autorisierung, DTO-Mapping, Validierung, Transaktionsstart, Domain-Aufruf, Persistenz, Fehlerbehandlung, Logging, Metriken und Trace-Kontext. Für kleine Demos kann man diese Themen ignorieren. In Enterprise-Systemen müssen sie bewusst standardisiert werden.
Kapitel 002 · Teil 1Java Sprache & Runtime im Enterprise-KontextJava-Version, Records, Virtual Threads, Exceptions, Collections und Modularität praxisnah verstehen.
Java-Version bewusst wählen
In Enterprise-Umgebungen ist die Java-Version eine Architekturentscheidung. Sie betrifft Laufzeit, Security-Patches, Framework-Kompatibilität, Build-Reproduzierbarkeit und Container-Images. Java 21 ist weiterhin eine sehr verbreitete moderne Basis, während Java 25 als aktuelle LTS-Version im Oracle-Ökosystem relevant ist. Für viele Frameworks bleibt Java 17 das Minimum, aber Java 21 ist häufig die sinnvolle produktive Basis.
| Entscheidung | Empfehlung | Begründung |
|---|---|---|
| Neues Enterprise-Projekt | Java 21 oder Java 25 prüfen | LTS, moderne Sprache, bessere Runtime-Features, lange Wartbarkeit |
| Migration von Java 8/11 | Zuerst Java 17/21-Kompatibilität herstellen | Abhängigkeiten, Reflection, javax/jakarta, alte App-Server prüfen |
| Build-Konfiguration | maven.compiler.release setzen | Reproduzierbares Bytecode-Ziel statt zufälliger lokaler JDK-Effekt |
| Container | JRE/JDK-Image bewusst wählen | Patch-Strategie, Größe, Security und Supportmodell klären |
<properties>
<!-- Enterprise-Regel: eine Java-Version bewusst festlegen, nicht implizit vom lokalen JDK erben. -->
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
</plugin>
</plugins>
</build>
Records, Value Objects und DTOs
Records sind ideal für unveränderliche Datencontainer: API-Requests, Responses, Commands, Events und einfache Value Objects. Nicht jede Entity sollte ein Record sein, weil JPA/Hibernate bei Entities besondere Anforderungen an Konstruktoren, Proxies und Lifecycle hat. Für fachliche Wertobjekte und Transportobjekte sind Records jedoch sehr lesbar.
public record PlaceOrderCommand(CustomerId customerId, List<Line> lines) {
public PlaceOrderCommand {
Objects.requireNonNull(customerId, "customerId");
lines = List.copyOf(lines);
if (lines.isEmpty()) throw new IllegalArgumentException("lines must not be empty");
}
public record Line(String sku, int quantity) {}
}
Virtual Threads richtig einordnen
Virtual Threads reduzieren den Aufwand blockierender I/O-Operationen, ersetzen aber keine Architekturarbeit. Sie lösen nicht automatisch Datenbank-Locks, schlechte SQLs, fehlende Timeouts oder unkontrollierte Nebenläufigkeit. Sie sind besonders interessant für viele gleichzeitige blockierende Requests, solange Bibliotheken und Frameworks korrekt mitspielen.
| Gut geeignet | Vorsicht |
|---|---|
| Viele blockierende HTTP-/DB-Aufrufe mit sauberem Timeout | CPU-lastige Arbeit profitiert kaum |
| Thread-per-request Modell mit moderner Runtime | ThreadLocal-Nutzung, Connection-Pool-Größen und Pinning prüfen |
| Migration ohne komplette Reactive-Umschreibung | Backpressure und Ressourcenlimits bleiben erforderlich |
Exception-Strategie
Enterprise-Code braucht eine klare Fehler-Taxonomie. Nicht jede Exception ist gleich: Validierungsfehler, Fachfehler, technische Recoverable-Fehler und technische Non-Recoverable-Fehler müssen unterschiedlich behandelt werden.
public sealed interface OrderFailure permits ValidationFailure, BusinessFailure, TechnicalFailure {}
public record ValidationFailure(String field, String message) implements OrderFailure {}
public record BusinessFailure(String code, String message) implements OrderFailure {}
public record TechnicalFailure(String system, String message, boolean retryable) implements OrderFailure {}
// Pattern: Result Object - erwartbare Fehler werden explizit modelliert statt als Zufalls-Exception geworfen.
public record Result<T>(T value, OrderFailure failure) {
public static <T> Result<T> ok(T value) { return new Result<>(value, null); }
public static <T> Result<T> fail(OrderFailure failure) { return new Result<>(null, failure); }
public boolean isOk() { return failure == null; }
}
Kapitel 003 · Teil 1Maven, Builds & Dependency ManagementReproduzierbare Enterprise-Builds, Parent-POMs, BOMs, Plugins und typische Fehler.
Maven als Architekturwerkzeug
Maven ist nicht nur ein Build-Tool. In Enterprise-Systemen beschreibt Maven Module, Abhängigkeitsrichtung, Versionierung, Plugin-Standards, Security-Checks, Testphasen, Packaging und Release-Konventionen. Ein schlecht gepflegter POM ist oft ein Symptom für schlechte Architekturgrenzen.
| Maven-Konzept | Enterprise-Bedeutung | Beispiel |
|---|---|---|
| Parent POM | Zentrale Plugin- und Qualitätsregeln | compiler, surefire, failsafe, enforcer |
| BOM | Versionen konsistent halten | Spring Boot BOM, Quarkus BOM, interne Plattform-BOM |
| Multi Module | Architekturgrenzen sichtbar machen | domain, application, adapters, boot |
| Profiles | Umgebungsunterschiede steuern | lokal, ci, native, integration-tests |
| Enforcer | Builds gegen Zufälle schützen | Java-Version, Dependency-Konvergenz, verbotene Abhängigkeiten |
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Modulgrenzen mit Maven erzwingen
Ein sauberer Enterprise-Schnitt vermeidet, dass der Web-Controller direkt auf JPA-Entities, SQL-Helfer oder externe REST-Clients zugreift. Maven-Module können diese Richtung erzwingen: Domain kennt nichts von Frameworks, Application kennt Ports, Adapter implementieren Ports.
order-platform
├── order-domain # reine Fachlichkeit, keine Frameworks
├── order-application # Use Cases, Ports, Transaktionsabstraktion
├── order-adapter-jpa # JPA/Hibernate Implementierung
├── order-adapter-rest # REST Controller / DTO Mapping
└── order-boot # Runtime, DI, Konfiguration, Startklasse
Typische Maven-Probleme
| Problem | Symptom | Korrektur |
|---|---|---|
| Transitive Version driftet | Lokal funktioniert es, CI oder Produktion nicht | dependency:tree prüfen, BOM nutzen, enforcer aktivieren |
| Zu viele Profile | Build ist nicht mehr reproduzierbar | Profile nur für echte Build-Varianten, Runtime-Konfig extern halten |
| Plugin-Versionen fehlen | Build ändert sich nach Maven/Plugin-Update | pluginManagement zentral definieren |
| Tests vermischt | Integrationstests laufen zufällig in unit-test Phase | Surefire für Unit, Failsafe für Integration |
| Framework-Abhängigkeit in Domain | Domain ist nicht mehr wiederverwendbar/testbar | Dependency-Richtung über Module korrigieren |
Kapitel 004 · Teil 1Jakarta EE: CDI, JTA, JAX-RS, JMS und BatchStandardbasierte Enterprise-Entwicklung mit Container-Diensten verstehen.
Jakarta EE als Standardplattform
Jakarta EE ist eine standardisierte Plattform für Enterprise-Anwendungen. Sie liefert Spezifikationen für Dependency Injection, REST, Persistence, Transactions, Messaging, Security, Validation, Batch und weitere Bereiche. Wichtig ist die Trennung zwischen Spezifikation und Implementierung: Jakarta EE definiert APIs und Verhalten, konkrete Server oder Frameworks liefern die Runtime.
| Spezifikation | Wofür sie gut ist | Typisches Missverständnis |
|---|---|---|
| CDI | Dependency Injection, Scopes, Events | CDI ist nicht nur @Inject, sondern Lebenszyklus und Kontexte |
| JTA | Transaktionsgrenzen über Ressourcen | Transaktion gehört an Use-Case-Grenze |
| JAX-RS | REST Endpunkte und Clients | HTTP-Status und Fehlervertrag sind Architektur, nicht Deko |
| JPA | Objekt/Relation-Mapping | Entity ist nicht automatisch Domain-Modell |
| JMS | Asynchrone Nachrichten | Message-Verarbeitung braucht Idempotenz und DLQ |
CDI und Application Service
CDI hilft, Objektgraphen kontrolliert zusammenzubauen. In Enterprise-Code sollte CDI nicht die Fachlogik ersetzen. Die Fachlogik bleibt in Domain- und Application-Services; CDI verdrahtet die Implementierungen.
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
@ApplicationScoped
public class InvoiceApplicationService {
@Inject InvoiceRepository invoices;
@Inject OrderClient orders;
@Inject DomainEventPublisher events;
// Pattern: Transaction Script an der Use-Case-Grenze - bewusst hier, nicht im Controller.
@Transactional
public InvoiceId createInvoiceFor(OrderId orderId) {
OrderSnapshot order = orders.load(orderId);
Invoice invoice = Invoice.from(order);
invoices.persist(invoice);
events.publish(new InvoiceCreated(invoice.id(), orderId));
return invoice.id();
}
}
JAX-RS Resource sauber schneiden
@Path("/invoices")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class InvoiceResource {
@Inject InvoiceApplicationService service;
@POST
public Response create(CreateInvoiceRequest request) {
InvoiceId id = service.createInvoiceFor(request.orderId());
return Response.created(URI.create("/invoices/" + id.value()))
.entity(new CreateInvoiceResponse(id.value()))
.build();
}
}
Jakarta EE 11 Modernisierung
Jakarta EE 11 ist relevant, weil es moderne Java-Sprachmerkmale besser berücksichtigt und Java 17+ als Basis setzt. Für Legacy-Projekte ist der wichtigste Schritt oft nicht sofort Jakarta EE 11, sondern die kontrollierte Migration von javax.* zu jakarta.*, die Aktualisierung des Application Servers und die Entkopplung alter EJB-/SOAP-/JSP-Schichten.
Kapitel 005 · Teil 1Spring Boot & Spring FrameworkAuto-Configuration verstehen, nicht blind benutzen: Controller, Services, Configuration, Profiles, Actuator.
Spring Boot in Enterprise-Systemen
Spring Boot ist stark, weil es Konventionen, Auto-Configuration, Starter, Actuator, Security-Integration, Testunterstützung und Cloud-Native-Betrieb zusammenbringt. Die Gefahr ist, dass Architekturentscheidungen in zufälligen Annotationen verschwinden. Gute Spring-Systeme halten Fachgrenzen explizit.
| Spring-Baustein | Nutzen | Enterprise-Regel |
|---|---|---|
| @Configuration | Explizite Beans und Adapter verdrahten | Konfiguration ist Infrastruktur, nicht Fachlogik |
| @Service | Use Cases oder technische Services markieren | Nicht jede Klasse mit @Service vollkleben |
| @Transactional | Transaktionsgrenze deklarieren | Anwendungsservice statt Controller |
| Actuator | Health, Metrics, Info, Readiness | Nur sichere Endpunkte extern freigeben |
| Profiles | Runtime-Konfiguration trennen | Keine Fachlogik per Profil verzweigen |
Controller, DTO und Use Case
@RestController
@RequestMapping("/api/orders")
class OrderController {
private final PlaceOrderUseCase placeOrder;
OrderController(PlaceOrderUseCase placeOrder) {
this.placeOrder = placeOrder;
}
@PostMapping
ResponseEntity<OrderResponse> create(@Valid @RequestBody PlaceOrderRequest request) {
OrderId id = placeOrder.handle(request.toCommand());
URI location = URI.create("/api/orders/" + id.value());
return ResponseEntity.created(location).body(new OrderResponse(id.value()));
}
}
Der Controller übersetzt HTTP in einen Use Case. Er sollte nicht entscheiden, wie Preise berechnet, Rechnungen erzeugt oder Events publiziert werden. Diese Entscheidungen gehören in Application Service und Domain.
Spring Configuration als Adapter-Zentrale
@Configuration
class OrderModuleConfiguration {
@Bean
PlaceOrderUseCase placeOrderUseCase(
OrderRepository repository,
DomainEventPublisher eventPublisher,
PricingPolicy pricingPolicy) {
return new PlaceOrderUseCase(repository, eventPublisher, pricingPolicy);
}
@Bean
PricingPolicy pricingPolicy(ProductCatalogClient catalog) {
// Pattern: Adapter + Strategy - Preisstrategie kann pro Kontext ausgetauscht werden.
return new CatalogBackedPricingPolicy(catalog);
}
}
Actuator und Betriebsfähigkeit
Enterprise-Anwendungen müssen betrieblich beobachtbar sein. Readiness bedeutet: Kann diese Instanz Traffic annehmen? Liveness bedeutet: Muss diese Instanz neugestartet werden? Health Checks dürfen nicht zu schwer sein und sollten Abhängigkeiten bewusst modellieren.
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
probes:
enabled: true
show-details: when_authorized
Kapitel 006 · Teil 1Quarkus & MicroProfileCloud-native Java, schnelle Starts, Standards, Fault Tolerance, Config, Health und OpenAPI.
Quarkus richtig verstehen
Quarkus optimiert Java für Container- und Cloud-Native-Szenarien. Es arbeitet stark zur Build-Zeit, unterstützt viele Standards aus Jakarta EE und MicroProfile und ist besonders interessant, wenn Startzeit, Speicherverbrauch, Developer Loop und native Images wichtig sind. Trotzdem bleiben Architekturprinzipien gleich: Fachlogik entkoppeln, Adapter schneiden, Fehlerverträge definieren.
@Path("/orders")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class OrderResource {
@Inject PlaceOrderUseCase placeOrder;
@POST
@Transactional
public Response create(@Valid PlaceOrderRequest request) {
OrderId id = placeOrder.handle(request.toCommand());
return Response.created(URI.create("/orders/" + id.value())).build();
}
}
MicroProfile als Microservice-Standardset
MicroProfile ergänzt Jakarta EE-orientierte APIs um typische Microservice-Themen: Config, REST Client, Fault Tolerance, Health, Metrics/Telemetry, OpenAPI und JWT. Das Ziel ist nicht, jedes Problem mit Annotationen zu lösen, sondern Standardverhalten für wiederkehrende Betriebssituationen bereitzustellen.
@ApplicationScoped
public class PartnerRatingClient {
@Inject
@RestClient PartnerApi partnerApi;
@Retry(maxRetries = 3, delay = 250)
@Timeout(1000)
@Fallback(fallbackMethod = "fallbackRating")
public PartnerRating loadRating(String partnerId) {
return partnerApi.rating(partnerId);
}
PartnerRating fallbackRating(String partnerId) {
return PartnerRating.unknown(partnerId);
}
}
| Annotation | Wirkung | Worauf achten |
|---|---|---|
| @Retry | Wiederholt einen fehlgeschlagenen Aufruf | Nur bei idempotenten oder sicheren Operationen |
| @Timeout | Begrenzt Wartezeit | Timeouts pro Partner und Use Case bewusst setzen |
| @Fallback | Definiert Ersatzverhalten | Fallback darf keine falsche Fachlichkeit vortäuschen |
| @CircuitBreaker | Schützt vor dauerhaften Partnerfehlern | Monitoring und Recovery-Verhalten planen |
Native Image einordnen
Native Images können Startzeit und Speicherverbrauch verbessern, bringen aber Build-Komplexität, Reflection-Konfiguration und Debugging-Besonderheiten mit. Sie sind wertvoll für Serverless, elastische Workloads oder sehr dichte Container-Landschaften, aber nicht automatisch die beste Wahl für jedes Enterprise-System.
Kapitel 007 · Teil 1MicronautCompile-Time DI, schlanke Microservices und testbare modulare Anwendungen.
Micronaut im Vergleich
Micronaut setzt stark auf Compile-Time Dependency Injection und vermeidet dadurch viel Runtime-Reflection. Das kann für Microservices, Serverless und schnelle Starts interessant sein. Für Teams ist vor allem wichtig, dass die Architektur nicht allein aus Framework-Magie besteht: Controller bleiben Adapter, Use Cases bleiben fachlich, Clients erhalten klare Timeout- und Fehlerregeln.
@Controller("/orders")
class OrderController {
private final PlaceOrderUseCase placeOrder;
OrderController(PlaceOrderUseCase placeOrder) {
this.placeOrder = placeOrder;
}
@Post
HttpResponse<OrderResponse> create(@Body @Valid PlaceOrderRequest request) {
OrderId id = placeOrder.handle(request.toCommand());
return HttpResponse.created(new OrderResponse(id.value()));
}
}
Wann Micronaut sinnvoll ist
| Szenario | Warum passend | Worauf achten |
|---|---|---|
| Neue Microservices | Leichtgewichtig, schnelle Starts, testbar | Team-Know-how und Ökosystem prüfen |
| Serverless | Startup und Speicher relevant | Cold Start ist nur ein Teil der Architektur |
| Modulare JVM-Anwendung | Compile-Time DI macht Abhängigkeiten sichtbar | Framework-spezifische Annotationen nicht in Domain ziehen |
| Migration von Spring | Konzepte ähnlich, Details anders | Auto-Configuration nicht 1:1 erwarten |
Client- und Konfigurationsdisziplin
In jedem Microservice-Framework gilt: Externe Clients brauchen Timeouts, Retry-Strategien, Fehler-Mapping und Observability. Ohne diese Regeln wird ein einzelner Partnerausfall schnell zur Kaskade im ganzen System.
Kapitel 008 · Teil 1JPA, Hibernate & PersistenzEntities, Aggregate, Fetching, Locking, Migrationen und Performancefallen.
Entity ist nicht automatisch Domain
JPA/Hibernate erleichtert Persistenz, kann aber Fachmodell und Datenmodell vermischen. Eine Entity ist ein persistierbares Objekt mit Lifecycle, Identität und Mapping-Regeln. Ein Domain-Aggregat ist ein fachlicher Konsistenzbereich. Beide können identisch sein, müssen es aber nicht.
package com.example.order.domain;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
// Pattern: Aggregate Root - Order schützt die Konsistenz der Positionsliste und Statusübergänge.
public class Order {
private final OrderId id;
private final CustomerId customerId;
private final List<OrderLine> lines = new ArrayList<>();
private OrderStatus status = OrderStatus.DRAFT;
public Order(OrderId id, CustomerId customerId) {
this.id = Objects.requireNonNull(id);
this.customerId = Objects.requireNonNull(customerId);
}
public static Order draftFor(CustomerId customerId) {
return new Order(new OrderId(UUID.randomUUID()), customerId);
}
public void addLine(String sku, int quantity, BigDecimal unitPrice) {
if (status != OrderStatus.DRAFT) {
throw new IllegalStateException("Only draft orders can be changed");
}
if (quantity <= 0 || unitPrice.signum() < 0) {
throw new IllegalArgumentException("Quantity and price must be valid");
}
lines.add(new OrderLine(sku, quantity, unitPrice));
}
public void place() {
if (lines.isEmpty()) throw new IllegalStateException("Order must contain at least one line");
status = OrderStatus.PLACED;
}
public BigDecimal total() {
return lines.stream()
.map(OrderLine::lineTotal)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
}
N+1 und Fetching verstehen
Viele Performanceprobleme entstehen nicht durch „Hibernate ist langsam“, sondern durch unpassende Fetch-Strategien für konkrete Use Cases. Schreibmodelle brauchen Konsistenz. Lesemodelle brauchen oft Projektionen.
// Problem: N+1 Queries, wenn jede Order später lazy ihre Lines lädt.
List<OrderEntity> orders = entityManager
.createQuery("select o from OrderEntity o", OrderEntity.class)
.getResultList();
orders.forEach(o -> log.info("{} lines", o.getLines().size()));
// Besser für Lese-Use-Case: gezielte Fetch-Strategie oder Projektion.
List<OrderSummary> summaries = entityManager
.createQuery("""
select new com.example.OrderSummary(o.id, c.name, sum(l.quantity * l.unitPrice))
from OrderEntity o
join o.customer c
join o.lines l
group by o.id, c.name
""", OrderSummary.class)
.getResultList();
Locking und Konsistenz
| Mechanismus | Wann nutzen | Risiko |
|---|---|---|
| Optimistic Locking | Viele parallele Lese-/Schreibzugriffe mit seltenen Konflikten | Konflikt muss fachlich sauber behandelt werden |
| Pessimistic Locking | Kurze kritische Abschnitte mit hohem Konfliktrisiko | Deadlocks, lange Transaktionen, Skalierungsprobleme |
| Unique Constraints | Eindeutige fachliche Regeln | Fehler müssen auf Fachfehler gemappt werden |
| Outbox Tabelle | DB-Änderung plus Event-Veröffentlichung | Zusätzlicher Prozess für Versand und Cleanup nötig |
Migrationen
Schema-Migrationen gehören in den Delivery-Prozess. Tools wie Flyway oder Liquibase sind nicht nur technische Helfer, sondern ein Vertrag zwischen Code-Version und Datenbankschema. Jede Migration sollte klein, nachvollziehbar, vorwärtskompatibel und rollback-bewusst sein.
-- V30260707_01__create_order_tables.sql
create table orders (
id uuid primary key,
customer_id uuid not null,
status varchar(30) not null,
version bigint not null default 0,
created_at timestamp not null
);
create table order_lines (
id uuid primary key,
order_id uuid not null references orders(id),
sku varchar(80) not null,
quantity integer not null check (quantity > 0),
unit_price numeric(19,2) not null check (unit_price >= 0)
);
Kapitel 009 · Teil 1Messaging: JMS, Kafka & Event-Driven ArchitectureAsynchronität, Events, Commands, DLQ, Idempotenz und Outbox.
Warum Messaging nicht nur Technik ist
Messaging wird oft eingeführt, um Systeme zu entkoppeln. Ohne fachliche Ereignisse, stabile Verträge und Fehlerstrategie entsteht aber nur verteiltes Chaos. Ein Event beschreibt eine fachlich abgeschlossene Tatsache. Ein Command fordert eine Aktion an. Diese Unterscheidung ist entscheidend für Ownership und Verantwortung.
| Nachrichtentyp | Bedeutung | Beispiel |
|---|---|---|
| Event | Etwas ist fachlich passiert | OrderPlaced, InvoiceCreated, PaymentReceived |
| Command | Ein System soll etwas tun | CreateInvoice, ReserveStock |
| Document Message | Zustand wird übertragen | CustomerSnapshotUpdated |
| Integration Event | Öffentlicher Vertrag zwischen Systemen | OrderPlacedV3 mit stabilen Feldern |
JMS und Kafka vergleichen
| Kriterium | JMS | Kafka |
|---|---|---|
| Grundidee | Queue/Topic Messaging in Enterprise Middleware | Distributed Event Log / Streaming Plattform |
| Typische Stärke | Transaktionale Enterprise-Integration, klassische App-Server, IBM MQ/Artemis | Hoher Durchsatz, Replay, Event Streaming, Consumer Groups |
| Nachrichtenmodell | Message wird konsumiert und bestätigt | Record bleibt im Log, Offset steuert Fortschritt |
| Fehlerstrategie | Redelivery, DLQ, Broker-Konfiguration | Retry Topics, DLQ, Offset-Management, Idempotenz |
| Architekturfrage | Wer besitzt Queue und Vertrag? | Wer besitzt Topic, Schema und Partition-Key? |
Idempotenz und DLQ
public class OrderPlacedConsumer {
private final KafkaConsumer<String, OrderPlacedEvent> consumer;
private final BillingService billing;
public void pollLoop() {
while (true) {
ConsumerRecords<String, OrderPlacedEvent> records = consumer.poll(Duration.ofSeconds(1));
for (ConsumerRecord<String, OrderPlacedEvent> record : records) {
try {
billing.createInvoice(record.value());
consumer.commitSync(Map.of(record.topicPartition(), new OffsetAndMetadata(record.offset() + 1)));
} catch (RecoverableBillingException ex) {
// Pattern: Retry / Dead Letter - nicht endlos denselben Datensatz blockieren.
retryOrSendToDlq(record, ex);
}
}
}
}
}
Outbox Pattern
Das Outbox Pattern löst das klassische Problem: Eine Datenbankänderung und ein Event müssen zuverlässig zusammengehören, aber Datenbank und Broker bilden keine einfache gemeinsame Transaktion. Deshalb schreibt der Use Case zuerst Fachdaten und Outbox-Eintrag in derselben DB-Transaktion. Ein separater Publisher versendet Outbox-Einträge an den Broker.
@Transactional
public void placeOrder(PlaceOrderCommand command) {
Order order = orderFactory.create(command);
order.place();
orderRepository.save(order);
// Pattern: Transactional Outbox - Event wird in derselben DB-Transaktion festgehalten.
outboxRepository.append(new OutboxMessage(
"OrderPlaced",
order.id().value().toString(),
json.serialize(OrderPlaced.from(order))
));
}
Kapitel 010 · Teil 1REST, SOAP & IntegrationHTTP-APIs, OpenAPI, WSDL, Bind/Process, Fehlerverträge und Versionierung.
REST als fachlicher Vertrag
REST ist nicht nur @GetMapping. Ein gutes API beschreibt Ressourcen, Statuscodes, Fehlerformat, Idempotenz, Versionierung, Paging, Filter, Security und Observability. Für Enterprise-Systeme sind Fehlerszenarien genauso wichtig wie Erfolgsszenarien.
| HTTP-Aspekt | Gute Praxis | Beispiel |
|---|---|---|
| POST | nicht-idempotente Erzeugung oder Aktion | POST /orders |
| PUT | idempotentes Ersetzen/Anlegen | PUT /customers/{id} |
| PATCH | partielle Änderung | PATCH /orders/{id}/address |
| 409 Conflict | fachlicher Konflikt | optimistic lock, duplicate order |
| 422 Unprocessable Entity | fachliche Validierung schlägt fehl | order without lines |
SOAP: Bind und Process trennen
Bei SOAP-Projekten entstehen Fehler oft dadurch, dass XML-Binding, Schema-Validierung und fachliche Verarbeitung vermischt werden. Das Binding wandelt XML in Java-Strukturen und zurück. Der Prozess führt den Use Case aus. Diese Trennung macht Tests, Fehlermapping und Migration viel leichter.
@WebService(targetNamespace = "urn:partner:rating:v1", name = "PartnerRatingPort")
public interface PartnerRatingPort {
@WebMethod(operationName = "GetPartnerRating")
PartnerRatingResponse getPartnerRating(PartnerRatingRequest request);
}
@WebService(endpointInterface = "com.example.partner.PartnerRatingPort")
public class PartnerRatingEndpoint implements PartnerRatingPort {
private final PartnerRatingService service;
@Override
public PartnerRatingResponse getPartnerRating(PartnerRatingRequest request) {
// Bind: SOAP/XML wurde bereits in Java-DTOs gemappt.
// Process: hier beginnt die fachliche Verarbeitung.
return PartnerRatingResponse.from(service.calculate(request.partnerId()));
}
}
Adapter für Partner-Systeme
public interface PartnerRatingGateway {
PartnerRating loadRating(PartnerId partnerId);
}
// Pattern: Anti-Corruption Layer - fremde SOAP-Strukturen bleiben außerhalb der Domain.
public class SoapPartnerRatingGateway implements PartnerRatingGateway {
private final PartnerRatingPort port;
@Override
public PartnerRating loadRating(PartnerId partnerId) {
PartnerRatingRequest request = PartnerRatingRequestMapper.toSoap(partnerId);
PartnerRatingResponse response = port.getPartnerRating(request);
return PartnerRatingMapper.toDomain(response);
}
}
Kapitel 011 · Teil 1Security: AuthN, AuthZ, OAuth2, JWT und SecretsSicherheit als Architekturquerschnitt statt späteres Add-on.
Security-Grundmodell
Enterprise Security besteht aus mehreren Schichten: Transport-Sicherheit, Authentifizierung, Autorisierung, Eingabevalidierung, Secret Management, Audit, sichere Defaults und Dependency-Sicherheit. Ein Framework kann vieles bereitstellen, aber die fachlichen Rechte und Datenzugriffe muss das Team modellieren.
| Begriff | Bedeutung | Typischer Fehler |
|---|---|---|
| Authentication | Wer bist du? | Login vorhanden, aber Token nicht validiert |
| Authorization | Was darfst du? | Nur Rollen auf Endpunkt, keine Objekt-/Mandantenprüfung |
| OAuth2/OIDC | Delegierte Autorisierung / Login | Frontend-Flow und Service-to-Service-Flow vermischen |
| JWT | tragbares Token mit Claims | Claims blind vertrauen ohne Signatur/Audience/Issuer-Prüfung |
| Secrets | Passwörter, Keys, Tokens | Secrets in Git, Dockerfile oder Logs |
Spring Security Resource Server
@Bean
SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.GET, "/actuator/health").permitAll()
.requestMatchers("/api/admin/**").hasAuthority("SCOPE_admin")
.requestMatchers("/api/orders/**").hasAuthority("SCOPE_orders")
.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
.csrf(csrf -> csrf.disable())
.build();
}
/customers/ muss geprüft werden, ob der Benutzer genau diesen Kunden sehen darf.Security im Code nicht verstreuen
public class CustomerAccessPolicy {
// Pattern: Policy Object - fachliche Zugriffsregel ist testbar und nicht in Controller verstreut.
public boolean canReadCustomer(UserPrincipal user, CustomerId customerId) {
return user.hasScope("customers:read") &&
(user.isEmployee() || user.customerIds().contains(customerId));
}
}
Kapitel 012 · Teil 1Observability & BetriebLogs, Metriken, Traces, Health, SLOs und Fehleranalyse im Enterprise-Betrieb.
Drei Signale plus Kontext
Observability bedeutet, das System aus seinen Signalen verstehen zu können: Logs erklären Ereignisse, Metriken zeigen Trends und SLO-Verletzungen, Traces zeigen verteilte Aufrufketten. Ohne Korrelation über Request-ID, Trace-ID und fachliche IDs bleibt Fehleranalyse langsam.
| Signal | Frage | Beispiel |
|---|---|---|
| Logs | Was ist passiert? | Order 123 konnte PartnerRating nicht laden |
| Metriken | Wie oft und wie schnell? | p95 latency, error rate, queue lag |
| Traces | Wo hängt die Kette? | Gateway -> Order -> Billing -> Partner API |
| Events | Welche fachlichen Zustände entstanden? | OrderPlaced, InvoiceCreated |
public class OrderTracingService {
private final Tracer tracer;
public void placeOrder(PlaceOrderCommand command) {
Span span = tracer.spanBuilder("order.place")
.setAttribute("customer.id", command.customerId().value().toString())
.startSpan();
try (Scope ignored = span.makeCurrent()) {
// Fachlogik bleibt gleich; Trace-Kontext wandert über HTTP/Kafka weiter.
handle(command);
} catch (Exception ex) {
span.recordException(ex);
span.setStatus(StatusCode.ERROR);
throw ex;
} finally {
span.end();
}
}
}
Health Checks richtig bauen
Readiness und Liveness müssen unterschiedliche Fragen beantworten. Eine DB-Störung kann Readiness beeinflussen, aber ein Service muss nicht sofort gekillt werden. Ein schlechter Liveness-Check kann bei externer Störung eine Neustart-Schleife erzeugen.
| Check | Frage | Sollte prüfen |
|---|---|---|
| Startup | Ist die Anwendung fertig initialisiert? | Migrationen, Cache-Warmup, kritische Konfiguration |
| Readiness | Kann diese Instanz Traffic annehmen? | DB erreichbar, Queue-Verarbeitung bereit, lokale Ressourcen |
| Liveness | Ist der Prozess intern kaputt? | Deadlock, fataler interner Zustand, nicht externe Partnerabhängigkeit |
SLO-orientierte Diagnose
Enterprise-Betrieb braucht Ziele: Verfügbarkeit, Latenz, Fehlerrate und Datenqualität. Metriken sind nicht nur Dashboards, sondern Entscheidungsgrundlage für Architektur: Caching, Partitionierung, Backpressure, Skalierung und Priorisierung.
Kapitel 013 · Teil 1Testing, Qualität & Architektur-ChecksUnit, Integration, Contract, Mutation, Architecture Tests und Testdatenstrategie.
Testpyramide für Enterprise Java
Enterprise-Tests sollen schnelles Feedback und reale Sicherheit kombinieren. Unit-Tests prüfen Domain-Regeln. Integrationstests prüfen DB, Broker und Framework-Konfiguration. Contract-Tests schützen Schnittstellen. End-to-End-Tests prüfen wenige kritische Gesamtabläufe.
| Testart | Ziel | Beispiel |
|---|---|---|
| Unit Test | Fachregel isoliert prüfen | Order darf ohne Lines nicht platziert werden |
| Integration Test | Adapter mit echter Infrastruktur prüfen | Repository gegen PostgreSQL |
| Contract Test | API-Vertrag stabil halten | Consumer erwartet Feld totalAmount |
| Architecture Test | Abhängigkeitsrichtung erzwingen | Domain darf Spring nicht importieren |
| E2E Test | kritischen Geschäftsfluss prüfen | Order -> Invoice -> Payment |
@Testcontainers
class OrderRepositoryIT {
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");
@Test
void persistsOrderWithLines() {
OrderRepository repository = repositoryFor(postgres.getJdbcUrl());
Order order = Order.draftFor(new CustomerId(UUID.randomUUID()));
order.addLine("SKU-1", 2, new BigDecimal("19.90"));
order.place();
repository.save(order);
assertThat(repository.findById(order.id())).isPresent();
}
}
Architekturtests
@AnalyzeClasses(packages = "com.example.order")
class ArchitectureRulesTest {
@ArchTest
static final ArchRule domain_is_framework_free = noClasses()
.that().resideInAPackage("..domain..")
.should().dependOnClassesThat().resideInAnyPackage(
"org.springframework..", "jakarta.persistence..", "jakarta.ws.rs.."
);
@ArchTest
static final ArchRule adapters_do_not_call_each_other = noClasses()
.that().resideInAPackage("..adapter..")
.should().dependOnClassesThat().resideInAPackage("..adapter..");
}
Kapitel 014 · Teil 1Deployment, Container, Kubernetes & OpenShiftVom JAR zum betriebenen Service: Images, Ressourcen, Probes, Config, Secrets und Rollouts.
Container ist kein Deployment-Konzept allein
Ein Dockerfile macht noch kein betreibbares System. Enterprise Deployment braucht Versionierung, Konfiguration, Secrets, Ressourcen, Probes, Rollout-Strategien, Migrationsplan, Monitoring und Incident-Fähigkeit.
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/order-service.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75", "-jar", "app.jar"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
selector:
matchLabels: { app: order-service }
template:
metadata:
labels: { app: order-service }
spec:
containers:
- name: app
image: registry.example.com/order-service:1.0.0
ports: [{ containerPort: 8080 }]
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
resources:
requests: { cpu: "250m", memory: "512Mi" }
limits: { cpu: "1", memory: "1024Mi" }
Konfiguration und Secrets
| Datenart | Wohin | Nicht tun |
|---|---|---|
| Normale Konfiguration | ConfigMap, Environment, Application Config | Nicht hart im Code verdrahten |
| Secrets | Secret Store / Kubernetes Secret / Vault | Nicht in Git oder Image bauen |
| Feature Flags | zentrales Flag-System oder sichere Konfig | Nicht heimlich Fachlogik per Profile duplizieren |
| DB-Migration | CI/CD oder kontrollierter Job | Nicht automatisch unkontrolliert bei jedem Pod-Start |
Rollout und Rückwärtskompatibilität
Rolling Updates bedeuten, dass alte und neue Versionen kurzzeitig gleichzeitig laufen. APIs, Events und Datenbankschema müssen dafür kompatibel sein. Eine Datenbankspalte entfernen ist fast nie ein einzelner Schritt; zuerst hinzufügen, doppelt schreiben/lesen, migrieren, dann später entfernen.
Kapitel 015 · Teil 1Architektur- und EntwurfsmusterPattern nicht als Theorie, sondern mit Zweck, Einsatzort und Warnsignal.
Wichtige Muster im Beispielprojekt
| Pattern | Zweck | Einsatzort | Warnsignal |
|---|---|---|---|
| Aggregate Root | Konsistenz innerhalb einer fachlichen Grenze schützen | Order verwaltet Lines und Status | Andere Klassen ändern interne Listen direkt |
| Repository | Persistenz hinter fachlichem Port verstecken | OrderRepository | Domain hängt an EntityManager |
| Application Service | Use Case orchestrieren | PlaceOrderUseCase | Controller enthält Geschäftslogik |
| Ports & Adapters | Frameworks austauschbar halten | Domain/Application vs REST/JPA/Kafka | Adapter rufen andere Adapter direkt auf |
| Factory | Konsistente Erzeugung komplexer Objekte | OrderFactory | new über den ganzen Code verstreut |
| Strategy | Austauschbare Fachvariante | PricingPolicy | if/else-Ketten für Preislogik |
| Policy Object | Autorisierung/Fachregel testbar kapseln | CustomerAccessPolicy | Security-Regeln in Controller verstreut |
| Outbox | DB-Commit und Event zuverlässig verbinden | OutboxMessage | Event nach Commit geht verloren |
| Anti-Corruption Layer | Fremde Modelle fernhalten | SOAP Partner Gateway | WSDL-Klassen in Domain |
Monster-Methode refactoren
Viele Legacy-Systeme enthalten Methoden, die Validierung, Mapping, DB-Zugriff, SOAP-Aufruf, Statusänderung, Logging und Fehlerbehandlung mischen. Refactoring beginnt nicht mit „alles neu“, sondern mit sichtbaren Schnitten.
public InvoiceId createInvoice(CreateInvoiceRequest request) {
validate(request);
OrderSnapshot order = orderGateway.load(request.orderId());
Invoice invoice = invoiceFactory.from(order);
invoiceRepository.save(invoice);
outbox.append(InvoiceCreated.from(invoice));
return invoice.id();
}
Entscheidungsregeln
| Frage | Wenn ja | Wenn nein |
|---|---|---|
| Ist die Regel fachlich stabil? | In Domain/Policy modellieren | In Application/Adapter lassen |
| Ist die Abhängigkeit extern? | Port definieren und Adapter bauen | Direkter Aufruf kann ok sein |
| Muss es transaktional konsistent sein? | Use-Case-Grenze festlegen | Asynchrones Event prüfen |
| Muss ein Consumer später replayen? | Event-Versionierung und Idempotenz planen | Command/Request genügt vielleicht |
| Muss es unabhängig deploybar sein? | API/Event-Vertrag hart pflegen | Modularer Monolith kann reichen |
Kapitel 016 · Teil 1Legacy-Modernisierung: Java EE, EJB, SOAP, JSP zu modernem JavaVerstehen, absichern, strangeln, extrahieren und modernisieren ohne Blindflug.
Modernisierung beginnt mit Verstehen
Legacy-Code ist nicht automatisch schlecht. Er enthält Geschäftsregeln, Ausnahmen, historische Partnerverträge und Produktionswissen. Modernisierung bedeutet, dieses Wissen zu sichern, bevor Technik ersetzt wird.
| Phase | Ziel | Artefakt |
|---|---|---|
| Inventur | Systeme, Schnittstellen, Jobs, DB, Deployments verstehen | Systemlandkarte, Abhängigkeitsmatrix |
| Absicherung | Tests und Observability für kritische Pfade schaffen | Characterization Tests, Logs, Traces |
| Schnitt setzen | Neue API/Fassade oder Strangler-Kante definieren | Adapter, Facade, Proxy, Routing-Regel |
| Extraktion | Fachliche Capability herauslösen | Modul oder Service mit Vertrag |
| Ablösung | Traffic umstellen, Altpfad entfernen | Migrationsreport, Runbook, Rückbauplan |
Strangler Fig praktisch
public class OrderFacade {
private final LegacyOrderService legacy;
private final ModernOrderService modern;
private final MigrationSwitch migrationSwitch;
// Pattern: Facade + Strangler Fig - Aufrufer bleiben stabil, Implementierung wandert schrittweise.
public OrderResponse placeOrder(PlaceOrderRequest request) {
if (migrationSwitch.useModernPath(request.customerSegment())) {
return modern.placeOrder(request);
}
return legacy.placeOrder(request);
}
}
javax zu jakarta
Die Umstellung von javax.* auf jakarta.* ist nicht nur Suchen/Ersetzen. Application Server, Libraries, Annotation Processor, SOAP/JAX-WS, JPA Provider, Validation, Security und Tests müssen zusammenpassen. Besonders kritisch sind alte Bibliotheken, die noch javax-APIs erwarten.
Frameworks, Libraries & Referenzwissen
Migration, JVM, Spring Data, MicroProfile, REST/SOAP, Security, Observability, Resilience und große Sammlungen.
Kapitel 017 · Teil 2Java 21/25 Migration RoadmapVon Java 8/11/17 zu Java 21/25: Sprache, Build, Runtime, Libraries, Container und Tests sicher modernisieren.
Warum eine Java-Migration kein reines JDK-Update ist
Eine Enterprise-Java-Migration betrifft Quellcode, Bytecode, Build-Plugins, Container-Images, Reflection, Security Provider, TLS, JDBC-Treiber, Application Server, Libraries und Betriebsprozesse. Java 21 ist für viele Unternehmen die moderne produktive Basis; Java 25 ist die aktuelle LTS-Linie und sollte für neue Zielplattformen geprüft werden. Wichtig ist eine kontrollierte Sequenz statt Big Bang.
Empfohlene Reihenfolge
Zuerst wird der Build reproduzierbar gemacht: Maven Compiler Plugin, Toolchains, Enforcer und CI-Image. Danach werden Tests und Characterization Tests ergänzt. Anschließend kommen Library-Upgrades, javax/jakarta-Analyse, Container-Images, Performancevergleich und produktionsnahe Lasttests.
Typische Modernisierungsgewinne
Records reduzieren DTO-Boilerplate, sealed types machen Fehler- und Statusmodelle klarer, Pattern Matching vereinfacht Routinglogik und Virtual Threads können blockierende I/O-Workloads vereinfachen. Der Gewinn entsteht aber erst, wenn Code und Architektur darauf vorbereitet sind.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
<properties>
<maven.compiler.release>21</maven.compiler.release>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals><goal>toolchain</goal></goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>21</version>
<vendor>any</vendor>
</jdk>
</toolchains>
</configuration>
</plugin>
</plugins>
</build>
public sealed interface MigrationRisk permits BuildRisk, RuntimeRisk, LibraryRisk {}
public record BuildRisk(String plugin, String reason) implements MigrationRisk {}
public record RuntimeRisk(String component, String reason) implements MigrationRisk {}
public record LibraryRisk(String dependency, String reason) implements MigrationRisk {}
public static String owner(MigrationRisk risk) {
return switch (risk) {
case BuildRisk ignored -> "Build/CI Team";
case RuntimeRisk ignored -> "Platform Team";
case LibraryRisk ignored -> "Application Team";
};
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Nur lokal kompilieren | CI, Docker-Image und Runtime können trotzdem altes Verhalten haben. |
| javax/jakarta unterschätzen | Package-Wechsel betrifft Code, Libraries, Server und Tests. |
| Performance nicht vergleichen | Neue Runtime kann andere GC-, TLS- oder Threading-Eigenschaften haben. |
Kapitel 018 · Teil 2JVM Performance, Speicher & DiagnoseHeap, GC, JFR, Thread Dumps, Connection Pools, Virtual Threads und messbare Performance-Hypothesen.
Performance beginnt vor dem Tuning
Viele Performanceprobleme entstehen durch fachliche oder architektonische Entscheidungen: zu große Aggregate, N+1 Queries, zu lange Transaktionen, fehlende Pagination, ungünstige Batchgrößen oder Remote Calls in kritischen Pfaden. JVM-Flags sind selten die erste Lösung.
Diagnosewerkzeuge
GC-Logs zeigen Speicher- und Pausenverhalten. JFR zeigt Locks, Methoden, Allocation, I/O und Threads. Thread Dumps helfen bei Deadlocks und blockierenden Aufrufen. Metriken zeigen Trends, Traces zeigen verteilte Latenz.
Virtual Threads im Betrieb
Virtual Threads können blockierende I/O-Szenarien vereinfachen, aber Datenbank- und HTTP-Pools bleiben Ressourcen. Wenn 10.000 virtuelle Threads auf 30 DB-Verbindungen warten, ist die Datenbank weiterhin die Grenze.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
java \
-XX:StartFlightRecording=filename=/var/log/order/startup.jfr,dumponexit=true \
-Xlog:gc*:file=/var/log/order/gc.log:time,uptime,level,tags \
-XX:MaxRAMPercentage=75 \
-jar order-service.jar
// Anti-Pattern: alle Datensätze laden und im Speicher filtern.
List<Order> all = orderRepository.findAll();
return all.stream().filter(Order::isOpen).toList();
// Besser: fachliche Query mit Limit und Sortierung.
return orderRepository.findOpenOrders(PageRequest.of(0, 100));
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Heap immer erhöhen | Mehr Heap kann Pausen verlängern und Ursachen verdecken. |
| Nur Durchschnittslatenz messen | p95/p99 sind für Nutzer und SLOs wichtiger. |
| Thread Dump ohne Kontext | Ohne TraceId, Metriken und Logs bleibt Analyse unvollständig. |
Kapitel 019 · Teil 2Spring Data, JDBC, JPA & Read ModelsRepository-Methoden, Projections, Specifications, JdbcClient, CQRS-light und saubere Query-Grenzen.
Repository ist keine Abkürzung um Use Cases herum
Spring Data spart Code, aber Controller sollten nicht direkt Repositories orchestrieren. Der Use Case definiert, welche Daten fachlich gebraucht werden, und das Repository liefert eine passende Abfrage.
Read Model statt Entity-Leak
Listenansichten, Suchseiten und Reports brauchen selten komplette Aggregates. Projections oder eigene Read Models reduzieren Datenvolumen und verhindern Lazy-Loading-Fallen.
JPA und JDBC kombinieren
JPA eignet sich für Aggregate und transaktionale Änderungen. JDBC oder SQL-Projections sind oft klarer für komplexe Reports, Massenabfragen und optimierte Read-Modelle.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
public interface OrderListProjection {
UUID getId();
String getCustomerNumber();
BigDecimal getTotalAmount();
Instant getCreatedAt();
}
interface OrderJpaRepository extends JpaRepository<OrderEntity, UUID> {
List<OrderListProjection> findByStatusOrderByCreatedAtDesc(OrderStatus status);
}
public List<OrderListView> findOpenOrdersForDashboard() {
return jdbcClient.sql("""
select o.id, c.customer_number, o.total_amount, o.created_at
from orders o
join customers c on c.id = o.customer_id
where o.status = :status
order by o.created_at desc
limit 100
""")
.param("status", "OPEN")
.query(OrderListView.class)
.list();
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Derived Query wird Roman | Lange Methodennamen sind schwer wartbar. |
| Entity als API-Vertrag | Persistenzdetails werden öffentlich. |
| Keine Index-Strategie | Gute Java-Abfrage hilft nicht bei schlechter DB-Struktur. |
Kapitel 020 · Teil 2MicroProfile Deep DiveConfig, REST Client, Fault Tolerance, JWT, Health, OpenAPI und Telemetry als Standard-Bausteine.
MicroProfile als Enterprise-Standardisierung
MicroProfile reduziert Wildwuchs bei Microservices. Statt jedes Team eigene Health Checks, REST Clients, Retries und API-Dokumentation baut, liefern Spezifikationen ein gemeinsames Programmiermodell.
Fault Tolerance richtig einsetzen
Timeout kommt vor Retry. Retry braucht Idempotenz. Circuit Breaker braucht Metriken. Bulkheads verhindern, dass ein langsames System alle Ressourcen blockiert.
Health ist kein Monitoring-Ersatz
Health Checks steuern Plattformverhalten. Monitoring erklärt Trends, Fehler und Latenzen. Liveness, Readiness und Startup sollten getrennt werden.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
@RegisterRestClient(configKey = "customer-api")
public interface CustomerClient {
@GET
@Path("/customers/{id}")
@Timeout(1000)
@Retry(maxRetries = 2, delay = 100)
CustomerDto find(@PathParam("id") String id);
}
@Readiness
@ApplicationScoped
public class DatabaseReadiness implements HealthCheck {
public HealthCheckResponse call() {
boolean ok = database.ping(Duration.ofSeconds(1));
return HealthCheckResponse.named("database").status(ok).build();
}
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Retry ohne Budget | Aufrufe werden langsamer und Last steigt. |
| Health prüft alles | Eine Partnerstörung darf nicht zwingend Liveness töten. |
| OpenAPI ohne Review | Generierte Spezifikation ersetzt kein API-Design. |
Kapitel 021 · Teil 2Micronaut Deep DiveCompile-Time DI, AOT, HTTP Clients, Configuration, Tests und Framework-Entscheidung.
Compile-Time statt Laufzeit-Magie
Micronaut erzeugt viel Metadatenarbeit zur Compile-Zeit. Das reduziert Reflection und kann schnelle Starts sowie geringeren Speicherbedarf unterstützen.
Wann Micronaut passt
Micronaut ist interessant für Microservices, Serverless, modulare Services und Teams, die Compile-Time DI bewusst nutzen wollen. Entscheidend bleibt die Unternehmensreife: Wissen, Support, Libraries und Betrieb.
Framework-Migration realistisch bewerten
Ein Wechsel von Spring oder Jakarta EE zu Micronaut ist nicht nur Annotationstausch. Konfiguration, Testing, Security, Datenzugriff, Observability und Build-Prozess müssen zusammen betrachtet werden.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
@Controller("/orders")
public class OrderController {
private final PlaceOrderUseCase placeOrder;
public OrderController(PlaceOrderUseCase placeOrder) {
this.placeOrder = placeOrder;
}
@Post
HttpResponse<IdResponse> place(@Body PlaceOrderRequest request) {
OrderId id = placeOrder.place(request.toCommand());
return HttpResponse.created(new IdResponse(id.value()));
}
}
@ConfigurationProperties("partner.billing")
public record BillingConfiguration(
URI baseUrl,
Duration timeout,
int maxRetries
) {}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Annotation Processing falsch konfiguriert | Build schlägt spät oder unklar fehl. |
| Framework nach Trend wählen | Team- und Betriebswissen sind genauso wichtig. |
| Zu große Kontexttests | Reine Domain braucht keinen Framework-Test. |
Kapitel 022 · Teil 2REST API Design & FehlerverträgeRessourcen, DTOs, Statuscodes, Problem Details, Versionierung, Pagination und Idempotency-Key.
REST ist ein Vertrag
REST APIs sind langlebige Verträge. Sie brauchen klare Ressourcen, Statuscodes, Fehlerformat, Security, Versionierung und Beispiele. Controller-Code ist nur die technische Oberfläche dieses Vertrags.
Problem Details im Enterprise-Kontext
Clients müssen unterscheiden können: Eingabe ungültig, Objekt nicht gefunden, fachlicher Konflikt, technische Störung, temporärer Fehler. Ein einheitliches Fehlerformat senkt Integrationsaufwand.
Idempotenz für kritische Kommandos
Bei Bestellung, Zahlung, Storno oder Buchung muss ein Retry ungefährlich sein. Ein Idempotency-Key verhindert doppelte Effekte.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
{
"type": "https://errors.example.com/order/credit-limit-exceeded",
"title": "Credit limit exceeded",
"status": 409,
"detail": "Customer C-4711 cannot place an order above 5000 EUR.",
"traceId": "4f7b9c0e6d2a",
"violations": []
}
public IdResponse place(String idempotencyKey, PlaceOrderRequest request) {
return idempotencyStore.executeOnce(idempotencyKey, () -> {
OrderId id = placeOrder.place(request.toCommand());
return new IdResponse(id.value());
});
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Immer 200 OK | Clients können Fehler nicht automatisiert behandeln. |
| Unbegrenzte Listen | Performance und Speicher kippen bei echten Daten. |
| Entity als Response | API wird an Datenbankmodell gekoppelt. |
Kapitel 023 · Teil 2SOAP Contract-First & Portal-IntegrationWSDL, XSD, Binding, Process, SOAP Faults und Fassade vor Altsystemen.
Warum SOAP wichtig bleibt
In Banken, Versicherungen, Behörden und B2B-Landschaften ist SOAP oft weiterhin produktiv. Verträge, XSD-Typen und WS-* Erweiterungen sind in solchen Umgebungen kein Zufall, sondern Stabilitätsfaktor.
Contract-first statt Java-first
Der Vertrag soll bewusst versioniert und fachlich geprüft werden. Java-Code wird gegen WSDL/XSD gebaut, nicht zufällig zum öffentlichen Vertrag.
Portal kommuniziert über Fassade
Ein Portal sollte Altsystemdetails nicht direkt kennen. Eine Fassade übersetzt Fehler, Datenformate und Sicherheitskontext.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
<xs:complexType name="PlaceOrderRequest">
<xs:sequence>
<xs:element name="customerNumber" type="xs:string" />
<xs:element name="orderLine" type="tns:OrderLine" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
public final class SoapBillingAdapter implements BillingPort {
private final BillingSoapClient client;
// Pattern: Adapter - SOAP-Vertrag bleibt außerhalb des Use Case.
public InvoiceId createInvoice(Order order) {
CreateInvoiceResponse response = client.createInvoice(SoapMapper.toRequest(order));
return new InvoiceId(response.getInvoiceNumber());
}
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| WSDL driftet durch Java-Code | Kleine Codeänderung wird Breaking Change. |
| Faults unstrukturiert | Clients können Fehler nicht zuverlässig auswerten. |
| Portal kennt Legacy-Codes | Modernisierung wird später blockiert. |
Kapitel 024 · Teil 2Event-Driven Architecture vertieftDomain Events, Kafka, JMS, Outbox, Schema Evolution, Ordering, Replay und DLQ.
Event ist eine fachliche Tatsache
Ein Event beschreibt, was passiert ist: OrderPlaced, PaymentReserved, InvoiceCreated. Es ist kein technischer Dump einer Datenbankzeile.
Outbox als Zuverlässigkeitsmuster
Datenänderung und Event-Erfassung werden in derselben Datenbanktransaktion gespeichert. Ein Publisher publiziert später zuverlässig an Broker oder Streaming-Plattform.
Consumer sind eigenständige Systeme
Consumer brauchen Idempotenz, Schema-Toleranz, Monitoring, Retry-Strategie und Dead Letter Queue. Ein Event macht Integration nicht automatisch einfach.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
public record OrderPlacedEvent(
UUID eventId,
UUID orderId,
String customerNumber,
BigDecimal totalAmount,
Instant occurredAt,
int schemaVersion
) {}
public void onOrderPlaced(OrderPlacedEvent event) {
if (processedEvents.exists(event.eventId())) {
return;
}
billingService.createInvoice(event.orderId());
processedEvents.markProcessed(event.eventId());
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Event zu klein | Consumer müssen synchron nachladen. |
| Event zu groß | Interne Modelle werden gekoppelt. |
| Kein Schema-Konzept | Consumer brechen bei harmlosen Änderungen. |
Kapitel 025 · Teil 2Security Deep Dive: OAuth2, OIDC, JWT & PoliciesIdentity Provider, Claims, Rollen, Objektberechtigung, Service-to-Service, Secrets und Audit.
Security beginnt bei Identität
Authentifizierung klärt, wer aufruft. Autorisierung klärt, was dieser Aufrufer im konkreten Kontext darf. Enterprise-Systeme brauchen häufig Objekt-, Mandanten- und Prozessberechtigungen.
JWT ist kein Sicherheitszauber
Token müssen auf Signatur, Ablaufzeit, Audience, Issuer und Scopes geprüft werden. Claims sollten stabil, minimal und fachlich sinnvoll sein.
Service-to-Service getrennt betrachten
Maschinenidentität ist nicht Nutzeridentität. Interne Kommunikation braucht Client Credentials, mTLS, Netzwerkregeln oder Plattformmechanismen.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
@PreAuthorize("hasAuthority('ORDER_APPROVE') and @orderSecurity.canAccess(#id)")
public void approve(OrderId id) {
approveOrderUseCase.approve(id);
}
public CurrentUser currentUser(Jwt jwt) {
return new CurrentUser(
jwt.getSubject(),
jwt.getClaimAsStringList("groups"),
jwt.getAudience()
);
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Rolle ersetzt Fachrecht | Ein Nutzer mit Rolle darf nicht jedes Objekt sehen. |
| Secrets im Image | Rotation wird schwierig und Sicherheitsrisiko steigt. |
| Token zu groß | Jede Anfrage transportiert unnötige Daten. |
Kapitel 026 · Teil 2Observability Deep Dive: OpenTelemetry & BetriebLogs, Metrics, Traces, Baggage, Sampling, SLOs, Dashboards und fachliche Nachvollziehbarkeit.
Drei Signale verbinden
Logs erklären Details, Metriken zeigen Verhalten über Zeit, Traces verbinden Aufrufe über Systemgrenzen. Gute Observability macht fachliche Vorgänge sichtbar.
Trace-Kontext durchreichen
TraceId und fachliche IDs wie orderId oder customerId müssen über HTTP, Messaging und Batch hinweg nachvollziehbar bleiben. Dabei dürfen sensible Daten nicht unkontrolliert in Logs landen.
SLO statt Dashboard-Sammlung
Dashboards sind nur hilfreich, wenn klar ist, welche Service-Level-Ziele gelten: Latenz, Fehlerrate, Verfügbarkeit, Queue Lag, Durchsatz.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
Span span = Span.current();
span.setAttribute("business.operation", "place-order");
span.setAttribute("order.id", order.id().value().toString());
span.setAttribute("customer.id", order.customerId().value());
log.info("order_placed order={} customer={} total={} traceId={}",
order.id().value(), order.customerId().value(), order.total(), MDC.get("traceId"));
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| PII in Logs | Datenschutz und Security werden verletzt. |
| Nur technische Metriken | Fachlicher Zustand bleibt unsichtbar. |
| Sampling ohne Regeln | Fehlerhafte oder langsame Requests fehlen im Trace-System. |
Kapitel 027 · Teil 2Resilience Patterns: Timeout, Retry, Circuit BreakerFehler in verteilten Enterprise-Systemen begrenzen: Bulkhead, Backpressure, Fallback und Idempotenz.
Teilfehler sind normal
Remote APIs, Broker und Datenbanken können langsam, partiell gestört oder nur für bestimmte Operationen fehlerhaft sein. Resilience verhindert, dass ein Fehler das ganze System mitreißt.
Timeout vor Retry
Jeder Retry braucht ein Zeitbudget und Idempotenz. Ohne Timeout verstärkt Retry die Last. Ohne Idempotenz erzeugt Retry doppelte Geschäftsvorfälle.
Fallback darf nicht lügen
Ein Fallback kann degradieren, aber er darf keinen fachlichen Erfolg vortäuschen. Wenn Zahlung unklar ist, sollte die Bestellung auf WAITING_FOR_PAYMENT stehen, nicht APPROVED.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
resilience4j:
timelimiter:
instances:
payment:
timeout-duration: 2s
retry:
instances:
payment:
max-attempts: 2
wait-duration: 100ms
circuitbreaker:
instances:
payment:
failure-rate-threshold: 50
sliding-window-size: 20
public PaymentDecision reservePayment(Order order) {
try {
return paymentClient.reserve(order.paymentRequest());
} catch (TimeoutException ex) {
return PaymentDecision.pending("PAYMENT_TIMEOUT");
}
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Retry bei Zahlung ohne Idempotency-Key | Doppelte Reservierung möglich. |
| Circuit Breaker ohne Metrik | Niemand versteht, warum Calls blockiert werden. |
| Bulkheads fehlen | Ein langsamer Partner verbraucht alle Threads. |
Kapitel 028 · Teil 2Batch, Scheduler & LangläuferSpring Batch, Jakarta Batch, CronJobs, Chunking, Restartability, Skip/Retry und fachliche Nachweise.
Batch ist produktionskritisch
Rechnungsläufe, Exporte, Importe, Mahnungen, Datenabgleiche und Reports laufen oft als Batch. Fehler dort sind nicht kleiner als Fehler in APIs.
Restartability planen
Ein Batch muss nach Fehler weiterlaufen können. Dafür braucht er Fortschrittsstatus, eindeutige Schlüssel, Checkpoints, Fehlerlisten und klare Wiederanlaufregeln.
Scheduler ist nur Auslöser
Die fachliche Logik gehört in Use Cases. Dann kann derselbe Prozess per Cron, manuell, Event oder API gestartet werden.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
@Bean
Step invoiceExportStep(JobRepository jobs, PlatformTransactionManager tx) {
return new StepBuilder("invoiceExport", jobs)
.<Invoice, ExportLine>chunk(500, tx)
.reader(invoiceReader())
.processor(invoiceProcessor())
.writer(exportWriter())
.faultTolerant()
.skip(InvalidInvoiceException.class)
.skipLimit(100)
.build();
}
public record BatchItemKey(String jobName, String businessKey, LocalDate businessDate) {}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Keine Wiederanlaufstrategie | Fehler führen zu manueller Datenbankkorrektur. |
| Zu große Chunks | Locks und Rollbacks werden teuer. |
| Batch nicht beobachtbar | Niemand kennt Fortschritt, Fehler und Restmenge. |
Kapitel 029 · Teil 2Caching, Configuration & Feature FlagsCaffeine, Redis, JCache, TTL, Invalidierung, Externalized Config, Secrets und Toggles.
Caching ist fachliche Entscheidung
Cache verbessert Latenz und reduziert Last, aber erzeugt Stale Data. Deshalb müssen Aktualität, TTL, Invalidierung und Berechtigungen fachlich geklärt werden.
Konfiguration vom Build trennen
Ein Artefakt soll in mehreren Umgebungen laufen. URLs, Limits, Feature Flags und Secrets gehören in Runtime-Konfiguration, nicht in den Build.
Feature Flags mit Governance
Flags brauchen Owner, Ziel, Ablaufdatum und Entfernung. Sonst entsteht ein verstecktes zweites Architekturmodell im Code.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
public record PriceCacheKey(String tenantId, String sku, String currency) {}
@Cacheable(cacheNames = "prices", key = "#tenantId + ':' + #sku + ':' + #currency")
public Money price(String tenantId, String sku, String currency) {
return priceClient.load(tenantId, sku, currency);
}
public boolean shouldUseNewRiskCheck(Customer customer) {
return flags.enabled("new-risk-check")
&& customer.region().equals(Region.EU)
&& customer.createdAt().isAfter(Instant.parse("2025-01-01T00:00:00Z"));
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Mandant fehlt im Cache-Key | Daten können zwischen Kunden vermischt werden. |
| Secret im Git | Sicherheitsvorfall und Rotationsproblem. |
| Dauerhafte Feature Flags | Code wird unübersichtlich und schwer testbar. |
Kapitel 030 · Teil 2Architekturtests, Quality Gates & CI/CDArchUnit, Enforcer, Dependency Checks, Contract Tests, Testcontainers, Coverage und Build-Pipeline.
Quality Gates schützen Architektur
Gute Regeln werden automatisiert. Sonst gewinnen Zeitdruck und Copy-Paste. Architekturtests prüfen Modulgrenzen, Dependency-Regeln, verbotene Frameworks in der Domain und Namenskonventionen.
CI/CD als Lernsignal
Eine Pipeline soll schnell Feedback geben: Kompilierung, Unit Tests, Architekturtests, Integrationstests, Security Checks, Packaging und Deployment. Fehler müssen verständlich sein.
Nicht alles in einen Test werfen
Schnelle Tests laufen früh, teure Tests später. Contract Tests schützen Schnittstellen, Integrationstests prüfen Adapter, End-to-End Tests bleiben sparsam.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
@Test
void domain_must_not_depend_on_frameworks() {
noClasses().that().resideInAPackage("..domain..")
.should().dependOnClassesThat().resideInAnyPackage(
"org.springframework..", "jakarta.persistence..", "jakarta.ws.rs..")
.check(importedClasses);
}
stages:
- compile
- unit-test
- architecture-test
- integration-test
- dependency-scan
- package
- deploy-dev
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Architektur nur im Wiki | Regeln werden nicht eingehalten. |
| Zu langsame Pipeline | Teams umgehen Tests. |
| Security erst vor Release | Dependency-Risiken werden spät sichtbar. |
Kapitel 031 · Teil 2Framework- und Library-AuswahlmatrixSpring Boot, Jakarta EE, Quarkus, Micronaut, Hibernate, Kafka, Maven und OpenTelemetry fachlich vergleichen.
Keine pauschal beste Technologie
Framework-Auswahl hängt von Teamwissen, Betriebsplattform, Support, Performance, Standardisierung, Migration, Ökosystem und Lebensdauer ab. Eine Technologie kann fachlich falsch sein, obwohl sie technisch modern wirkt.
Bewertung mit Gewichtung
Kriterien sollten gewichtet werden: Teamkompetenz, Plattformstandard, Startzeit, Speicherbedarf, Standard-APIs, Observability, Security, Migration, Lizenz, Support und Recruiting.
Mehrere Stacks brauchen Governance
Wenn ein Unternehmen mehrere Frameworks nutzt, braucht es gemeinsame Mindeststandards für Security, Logging, Tracing, CI/CD, API-Fehler, Dependency Management und Betrieb.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
criteria:
team_experience: 5
platform_fit: 5
startup_time: 3
memory_usage: 3
standard_apis: 4
ecosystem: 5
migration_effort: 5
candidates:
spring_boot: { score: 31, note: "breites Ökosystem" }
jakarta_ee: { score: 28, note: "Standard und App-Server" }
quarkus: { score: 29, note: "Cloud-native und Build-Time" }
micronaut: { score: 26, note: "Compile-time DI" }
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Benchmark entscheidet allein | Wartung, Teamwissen und Betrieb fehlen. |
| Framework-Mix ohne Standards | Security und Observability driften. |
| Migration als Neuentwicklung | Fachliche Risiken werden unterschätzt. |
Matrix
| Technologie | Typ | Stärken | Achtung |
|---|---|---|---|
| Spring Boot | Framework/Runtime | Ökosystem, Produktivität, Actuator, Cloud-Integration | Auto-Konfiguration verstehen, Starter kontrollieren |
| Jakarta EE | Standardplattform | Spezifikationen, App-Server, langlebige Standards | Serverwahl, javax/jakarta-Migration |
| Quarkus | Framework/Runtime | Build-Time, Container, Native Option, MicroProfile | Extensions, Native-Kompatibilität |
| Micronaut | Framework | Compile-Time DI, schnelle Starts, Serverless | Teamwissen, Annotation Processing |
| Hibernate | ORM Library/Framework | JPA, Mapping, Query-Fähigkeiten | N+1, Lazy Loading, Migration |
| Kafka | Streaming Plattform/Client | Event Log, Replay, skalierbare Consumers | Schema, Ordering, DLQ, Idempotenz |
| OpenTelemetry | Observability Standard | Traces, Metrics, Logs standardisieren | PII, Sampling, Attributmodell |
Kapitel 032 · Teil 2Große Annotationen-SammlungEnterprise-Annotationen nach Kategorie: REST, DI, Transaktionen, JPA, Validation, Security, Resilience und Tests.
Annotationen sind Laufzeitverträge
Annotationen steuern Routing, Transaktionen, Scopes, Persistenz, Validierung, Security, Resilience und Tests. Sie sind kein Dekor, sondern Architekturverhalten.
Parameter verstehen
Viele Fehler entstehen durch Defaults: FetchType, Cascade, Propagation, Rollback-Regeln, consumes/produces, Retry-Anzahl, Timeout und Security-Ausdruck.
Kategorie statt Auswendiglernen
Wer Annotationen nach Verantwortungsbereich lernt, versteht schneller, warum und wo sie eingesetzt werden.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
@RestController
@RequestMapping(path = "/api/orders", produces = MediaType.APPLICATION_JSON_VALUE)
@Validated
public class OrderController {
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
public IdResponse place(@Valid @RequestBody PlaceOrderRequest request) {
return service.place(request);
}
}
@Entity
@Table(name = "orders")
public class OrderEntity {
@Id
private UUID id;
@Version // Optimistic Locking gegen verlorene Updates
private long version;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<OrderLineEntity> lines = new ArrayList<>();
}
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Annotation ohne Wirkmodell | Code sieht richtig aus, Verhalten ist aber unklar. |
| Zu viele Verantwortungen auf einer Klasse | Controller, Transaktion, Mapping und Security vermischen sich. |
| Defaultwerte ungeprüft | Produktion zeigt andere Effekte als erwartet. |
Annotationenkatalog
| Annotation | Bereich | Zweck | Wichtige Parameter | Risiko |
|---|---|---|---|---|
| @RestController | Spring MVC | REST Controller + ResponseBody | value/name | Entity direkt zurückgeben |
| @RequestMapping | Spring MVC | Pfad, Methode, Media Type | path, method, consumes, produces | Uneinheitliche Versionierung |
| @Path | JAX-RS | Ressourcenpfad | value | Pfadmodell nicht fachlich |
| @ApplicationScoped | CDI | Bean pro Anwendung | - | Mutable State |
| @RequestScoped | CDI | Bean pro Request | - | Async-Kontext falsch |
| @Transactional | Jakarta/Spring | Transaktionsgrenze | propagation/isolation/rollback | Proxy-Grenze, lange TX |
| @Entity | JPA | Persistenzklasse | name | API und Entity vermischen |
| @Version | JPA | Optimistic Locking | - | Lost Updates |
| @OneToMany | JPA | 1:n Beziehung | mappedBy/cascade/orphanRemoval/fetch | N+1 oder falsches Cascade |
| @Valid | Bean Validation | Objektgraph validieren | groups | Nur Controller-Validierung |
| @PreAuthorize | Spring Security | Methodenautorisierung | SpEL | Objektberechtigung fehlt |
| @RolesAllowed | Jakarta Security | Rollenprüfung | value | Rolle = Fachrecht |
| @Retry | MicroProfile FT | Retry-Regel | maxRetries/delay/retryOn | Nicht-idempotente Operation |
| @Timeout | MicroProfile FT | Zeitlimit | value | Timeout größer als Budget |
| @CircuitBreaker | MicroProfile FT | Fehlerkreis öffnen | threshold/window | Ohne Monitoring unklar |
| @RegisterRestClient | MicroProfile | REST Client registrieren | configKey | Timeout fehlt |
| @KafkaListener | Spring Kafka | Kafka Consumer | topics/groupId | Idempotenz fehlt |
| @Cacheable | Spring Cache | Methode cachen | cacheNames/key/condition | Mandant fehlt im Key |
| @ConfigurationProperties | Spring Boot | Konfiguration typisieren | prefix | Secrets/Defaults unklar |
| @QuarkusTest | Quarkus | Quarkus Integration Test | - | Zu groß für Domain |
| @MicronautTest | Micronaut | Micronaut Context Test | - | Container für Unit Test |
Kapitel 033 · Teil 2Glossar & Entwurfsmuster-SammlungFachliche und technische Begriffe plus wichtige Entwurfsmuster für Enterprise Java.
Glossar als Teamvertrag
Ein Glossar verbindet Fachbereich, Entwicklung, Test, Betrieb und Architektur. Es verhindert, dass derselbe Begriff in mehreren Teams unterschiedlich gemeint ist.
Pattern sind Werkzeuge, keine Dekoration
Entwurfsmuster sind hilfreich, wenn sie ein echtes Problem lösen: Abhängigkeiten kapseln, Erzeugung kontrollieren, Varianten austauschen, Integration robust machen oder Legacy-Sprache isolieren.
Dokumentation im Projekt
Verwendete Muster sollten im Code kurz markiert und zusätzlich in docs/design-patterns.md dokumentiert werden. Das hilft besonders bei Maven-/Java-Projekten und späterer Wartung.
Entscheidungen
| Entscheidung | Gute Praxis | Prüffrage |
|---|---|---|
| Fachliche Grenze | Zuerst Use Case, Invariante und Verantwortlichkeit klären. | Welche Geschäftsentscheidung wird geschützt? |
| Technische Grenze | Framework-/Library-Code hinter Port, Adapter oder Konfiguration kapseln. | Kann die Domain ohne Framework getestet werden? |
| Betrieb | Timeouts, Logs, Metriken, Traces, Security und Rollback definieren. | Wie erkennt der Betrieb Fehler rechtzeitig? |
Ausführliche Beispiele
| Pattern | Zweck | Einsatzort | Begründung |
|---|---|---|---|
| Adapter | Externes System kapseln | HttpPaymentAdapter | Use Case kennt kein HTTP |
| Repository | Persistenz verstecken | OrderRepository | Domain bleibt DB-unabhängig |
| Outbox | Events zuverlässig publizieren | OutboxPublisher | Kein verlorenes Event |
| Saga | Verteilten Prozess steuern | OrderSaga | Kompensation statt 2PC |
Typische Stolperfallen
| Stolperfalle | Warum gefährlich |
|---|---|
| Pattern um des Patterns willen | Überabstraktion macht Code schwerer. |
| Muster nicht dokumentiert | Spätere Teams erkennen Absicht nicht. |
| Legacy-Begriffe übernehmen | Alte Modellfehler werden ins neue System getragen. |
Glossar
| Begriff | Erklärung | Kontext |
|---|---|---|
| Aggregate | Fachliche Konsistenzgrenze mit Invarianten | DDD |
| Adapter | Technische Umsetzung eines Ports | Hexagonal |
| Anti-Corruption Layer | Übersetzt Legacy-Modell in neue Domäne | Migration |
| BOM | Zentrale Dependency-Versionierung | Maven |
| Bounded Context | Gültigkeitsbereich eines Modells | DDD |
| Circuit Breaker | Stoppt Aufrufe an gestörte Abhängigkeit | Resilience |
| DTO | Transportobjekt für API oder Adapter | API |
| Idempotenz | Mehrfachausführung ohne doppelten Effekt | Integration |
| Outbox | Event in gleicher DB-TX speichern | Messaging |
| Readiness Probe | Prüft Traffic-Fähigkeit eines Pods | Kubernetes |
| Saga | Langer Prozess mit Kompensation | Architektur |
| TraceId | ID zur Verfolgung über Systeme | Observability |
| Virtual Thread | Leichtgewichtiger Thread für blockierende I/O | Java |
Entwurfsmuster
| Pattern | Zweck | Einsatzort | Begründung |
|---|---|---|---|
| Adapter | Externes System hinter Port verstecken | PaymentAdapter, SoapBillingAdapter | Use Case bleibt technisch unabhängig |
| Repository | Persistenz als fachliche Sammlung kapseln | OrderRepository | Domain kennt keine DB |
| Factory Method | Erzeugung mit Invarianten bündeln | Order.place(...) | Objekte entstehen gültig |
| Strategy | Varianten austauschbar machen | ApprovalPolicy | Keine if-Ketten |
| Transactional Outbox | Events zuverlässig publizieren | OutboxPublisher | Kein verlorenes Event nach Commit |
| Saga | Verteilten Prozess steuern | OrderSaga | Kompensation statt 2PC |
| Anti-Corruption Layer | Legacy-Modell isolieren | LegacyCustomerMapper | Neue Sprache schützen |
Praxisprojekt & Architektur
Order & Billing Platform, Domain Modeling, Hexagonal Architecture, Framework-Umsetzungen und Refactoring.
Kapitel 034 · Teil 3Durchgehendes Praxisprojekt: Order & Billing PlatformEin durchgehendes Enterprise-Beispielsystem, das die Theorie der vorherigen Kapitel in einen praxisnahen Architektur- und Codezusammenhang bringt.
Zielbild
Das Praxisprojekt zeigt eine realistische Enterprise-Landschaft: Ein Kundenportal erzeugt Bestellungen, die Order-Domain prüft Invarianten, Inventory reserviert Bestand, Billing erzeugt Rechnungen und ein Event Backbone verteilt fachliche Ereignisse. Wichtig ist nicht, möglichst viele Technologien zu verwenden, sondern die Grenzen sauber sichtbar zu machen.
Fachlicher Schnitt
| Bounded Context | Verantwortung | Nicht-Verantwortung |
|---|---|---|
| Order | Bestellung anlegen, freigeben, stornieren | Rechnung berechnen |
| Billing | Rechnung und Zahlungsstatus | Bestellentscheidung |
| Inventory | Reservierung und Bestand | Kundenbonität |
| Notification | Benachrichtigung | Fachliche Entscheidung |
Module
shared-kernel
Gemeinsame primitive Fachtypen, Result-Typ und DomainEvent.
order-domain
Aggregate, Value Objects, Policies und Events ohne Framework-Abhängigkeit.
order-application
Use Cases und Ports. Hier entsteht der fachliche Prozess.
order-adapters
Repository, Outbox, Legacy-Adapter, Billing-Adapter.
spring-boot-app
HTTP- und Betriebsschicht für Spring Boot.
quarkus-app
Cloud-native Variante für Quarkus/MicroProfile.
docs
ADRs, Pattern-Dokumentation, Teststrategie, Runbooks.
Bestellablauf
- REST Controller nimmt
PlaceOrderRequestan. - Use Case validiert Command und lädt benötigte Stammdaten.
- Aggregate
Orderschützt Invarianten. - Repository speichert Order.
- Outbox speichert
OrderPlacedin derselben Transaktion. - Outbox Relay publiziert das Event später zuverlässig.
Code-Slice
public final class PlaceOrderUseCase {
private final OrderRepository orders; // Pattern: Repository Port
private final InventoryPort inventory; // Pattern: Port
private final TransactionRunner tx; // Pattern: Unit of Work Boundary
private final OutboxPort outbox; // Pattern: Transactional Outbox
public PlaceOrderUseCase(OrderRepository orders, InventoryPort inventory,
TransactionRunner tx, OutboxPort outbox) {
this.orders = orders;
this.inventory = inventory;
this.tx = tx;
this.outbox = outbox;
}
public OrderId handle(PlaceOrderCommand command) {
return tx.required(() -> {
inventory.reserve(command.customerId(), command.lines());
Order order = Order.place(command.customerId(), command.lines()); // Factory Method
orders.save(order);
outbox.appendAll(order.pullEvents()); // Outbox: Event wird mit Order atomar gespeichert
return order.id();
});
}
}
Typische Stolperfallen
| Fehler | Warum problematisch | Bessere Lösung |
|---|---|---|
| Controller enthält Geschäftslogik | Tests werden langsam und technische Details dominieren | Controller nur als Adapter verwenden |
| Event direkt nach DB-Save senden | Bei Crash nach Commit geht Event verloren | Transactional Outbox |
| Framework-Anmerkungen in Domain | Domain wird schwer testbar und schwer portierbar | Domain ohne Framework halten |
Kapitel 035 · Teil 3Domain Modeling, Use Cases & InvariantenDieses Kapitel zeigt, wie aus Fachlichkeit belastbare Java-Modelle entstehen: Value Objects, Aggregates, Policies, Events und Commands.
Fachbegriffe
Der größte Fehler in Enterprise-Projekten ist oft nicht technisch, sondern sprachlich: Kunde, Auftrag, Bestellung, Rechnung, Reservierung und Zahlung werden in jedem Team anders verstanden. Ein Domain Model zwingt das Team zu präzisen Begriffen.
Invarianten
| Invariante | Beispiel | Ort im Code |
|---|---|---|
| Eine Bestellung braucht mindestens eine Position | Leere Bestellung ist ungültig | Order.place |
| Menge muss positiv sein | quantity > 0 | OrderLine.of |
| Stornierte Order darf nicht fakturiert werden | Statuswechsel blockieren | Order.cancel / BillingPolicy |
| Event beschreibt fachliche Tatsache | OrderPlaced nach erfolgreicher Erzeugung | DomainEvent |
Value Objects
Value Objects reduzieren Primitive Obsession. Statt überall String customerId und BigDecimal amount zu verwenden, entstehen Typen mit Regeln.
public record Money(BigDecimal amount, Currency currency) {
public Money {
if (amount == null || currency == null) throw new IllegalArgumentException("Money requires amount and currency");
if (amount.scale() > 2) throw new IllegalArgumentException("Money supports cents only");
}
public Money plus(Money other) {
if (!currency.equals(other.currency)) throw new IllegalArgumentException("Currency mismatch");
return new Money(amount.add(other.amount), currency);
}
}
Aggregate
Ein Aggregate ist keine technische Entity-Sammlung. Es ist eine fachliche Konsistenzgrenze. Im Beispiel darf nur Order entscheiden, ob Positionen, Status und Events zusammen gültig sind.
Events
Ein Domain Event beschreibt, was fachlich passiert ist. Es ist nicht primär ein technischer Kafka-Record, sondern eine Wahrheit aus der Fachlichkeit.
Beispiel
public final class Order {
private final OrderId id;
private final CustomerId customerId;
private final List<OrderLine> lines = new ArrayList<>();
private final List<DomainEvent> events = new ArrayList<>();
private OrderStatus status;
private Order(OrderId id, CustomerId customerId) {
this.id = id;
this.customerId = customerId;
this.status = OrderStatus.NEW;
}
// Pattern: Factory Method - erzeugt nur fachlich gültige Orders.
public static Order place(CustomerId customerId, List<OrderLine> requestedLines) {
if (requestedLines == null || requestedLines.isEmpty()) {
throw new DomainRuleViolation("Eine Bestellung braucht mindestens eine Position");
}
Order order = new Order(OrderId.newId(), customerId);
requestedLines.forEach(order::addLine);
order.events.add(new OrderPlaced(order.id, customerId));
return order;
}
public void cancel(String reason) {
if (status == OrderStatus.INVOICED) {
throw new DomainRuleViolation("Fakturierte Bestellung kann nicht storniert werden");
}
status = OrderStatus.CANCELLED;
events.add(new OrderCancelled(id, reason));
}
}
Kapitel 036 · Teil 3Clean & Hexagonal Architecture im Enterprise-ProjektSaubere Architektur trennt Fachlichkeit von Framework, Datenbank, Messaging, SOAP und Deployment.
Problem
In klassischen Enterprise-Systemen landen Controller, EntityManager, SOAP-Client, JMS-Produzent und Geschäftsregeln oft in derselben Klasse. Dadurch ist jeder kleine Fachtest ein halber Integrationstest. Hexagonal Architecture schiebt technische Details an den Rand.
Architekturregeln
| Regel | Konsequenz |
|---|---|
| Domain importiert kein Spring, Jakarta, Hibernate oder Kafka | Fachmodell bleibt portierbar |
| Application Core kennt Ports, keine Adapter | Technik kann ausgetauscht werden |
| Adapter übersetzen technische Verträge | Legacy-Sprache bleibt draußen |
| Framework startet Anwendung, besitzt sie aber nicht | Use Cases bleiben unabhängig |
Ports
public interface BillingPort { // Pattern: Port
BillingReservation reserveInvoice(OrderId orderId, Money total);
}
public interface OrderRepository { // Pattern: Repository
void save(Order order);
Optional<Order> findById(OrderId id);
}
public interface ClockPort { // Pattern: Dependency Inversion
Instant now();
}
Adapter
public final class SoapBillingAdapter implements BillingPort { // Pattern: Adapter + ACL
private final LegacyBillingClient client;
private final LegacyBillingMapper mapper;
@Override
public BillingReservation reserveInvoice(OrderId orderId, Money total) {
LegacyInvoiceRequest request = mapper.toLegacyRequest(orderId, total);
LegacyInvoiceResponse response = client.reserve(request);
return mapper.toDomainReservation(response);
}
}
Testbarkeit
Der Use Case kann mit In-Memory-Ports getestet werden. Kein Webserver, keine Datenbank, kein Broker ist nötig.
@Test
void placeOrderWritesOutboxEvent() {
InMemoryOrderRepository orders = new InMemoryOrderRepository();
InMemoryOutbox outbox = new InMemoryOutbox();
PlaceOrderUseCase useCase = new PlaceOrderUseCase(orders, new AlwaysAvailableInventory(), TransactionRunner.noop(), outbox);
OrderId id = useCase.handle(sampleCommand());
assertThat(orders.findById(id)).isPresent();
assertThat(outbox.events()).hasSize(1);
}
Entscheidungen
Kapitel 037 · Teil 3Spring Boot Umsetzung im PraxisprojektSpring Boot wird als Laufzeit- und Adapterrahmen verwendet, nicht als Ersatz für fachliche Architektur.
Rolle von Spring
Spring Boot eignet sich für schnelle produktionsnahe Services mit Autoconfiguration, Actuator, Security-Integration und starkem Ökosystem. Im Architekturmodell sitzt Spring am Rand: Controller, Configuration, Security Filter, Repository-Implementierung und Observability.
Controller
@RestController
@RequestMapping("/api/orders")
final class OrderController { // Pattern: Inbound Adapter
private final PlaceOrderUseCase placeOrder;
OrderController(PlaceOrderUseCase placeOrder) {
this.placeOrder = placeOrder;
}
@PostMapping
ResponseEntity<OrderResponse> place(@Valid @RequestBody PlaceOrderRequest request) {
OrderId id = placeOrder.handle(request.toCommand());
return ResponseEntity.created(URI.create("/api/orders/" + id.value()))
.body(new OrderResponse(id.value(), "ACCEPTED"));
}
}
Konfiguration
Spring-Konfiguration verdrahtet Ports und Adapter. Der Use Case bleibt frei von Spring-Annotationen.
@Configuration
class OrderApplicationConfig {
@Bean
PlaceOrderUseCase placeOrderUseCase(OrderRepository orders,
InventoryPort inventory,
TransactionRunner tx,
OutboxPort outbox) {
return new PlaceOrderUseCase(orders, inventory, tx, outbox);
}
}
Transaktionen
Transaktionsgrenzen gehören in die Application-Schicht oder einen expliziten TransactionRunner. Dadurch bleibt klar, welcher Use Case atomar sein muss.
Betrieb
| Endpoint | Zweck |
|---|---|
| /actuator/health/readiness | Traffic-Fähigkeit prüfen |
| /actuator/metrics | Metriken für Betrieb und SLOs |
| /actuator/prometheus | Prometheus Scraping |
| /actuator/loggers | Temporäre Diagnose |
Fehlerbild
| Schlecht | Besser |
|---|---|
| @Transactional überall | Transaktionsgrenzen pro Use Case bewusst setzen |
| Entity direkt als API Response | DTO/Response-Vertrag stabil halten |
| Business-Logik im Controller | Controller als Adapter halten |
Kapitel 038 · Teil 3Jakarta EE Umsetzung im PraxisprojektJakarta EE zeigt Enterprise-Standardisierung mit CDI, JTA, JAX-RS, Persistence, Security und Batch.
Rolle von Jakarta EE
Jakarta EE ist besonders stark, wenn ein Unternehmen Standards, zertifizierte Runtime, Portabilität und klassische Enterprise-Fähigkeiten wie CDI, JTA, JAX-RS, Jakarta Persistence, Messaging und Batch bündeln möchte.
JAX-RS Resource
@Path("/orders")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class OrderResource { // Pattern: Inbound Adapter
@Inject PlaceOrderUseCase placeOrder;
@POST
public Response place(PlaceOrderRequest request, @Context UriInfo uriInfo) {
OrderId id = placeOrder.handle(request.toCommand());
URI location = uriInfo.getAbsolutePathBuilder().path(id.value()).build();
return Response.created(location).entity(new OrderResponse(id.value(), "ACCEPTED")).build();
}
}
CDI
CDI übernimmt Dependency Injection und Scopes. Auch hier sollte die Domain keine CDI-Annotationen benötigen.
JTA
@ApplicationScoped
public class JakartaTransactionRunner implements TransactionRunner { // Pattern: Unit of Work
@Transactional
public <T> T required(Supplier<T> work) {
return work.get();
}
}
Batch
Jakarta Batch eignet sich für kontrollierte, wiederanlaufbare Verarbeitung großer Datenmengen. Das Praxisprojekt nutzt Batch für nächtliche Rechnungsabgleiche.
Vergleich
| Aspekt | Jakarta EE | Spring Boot |
|---|---|---|
| Standardisierung | Sehr stark über Spezifikationen | Stark über Ökosystem und Konventionen |
| Runtime | Application Server oder kompatible Runtime | Embedded Runtime |
| Transaktionen | JTA standardisiert | Spring Transaction Abstraction |
| Cloud Native | über moderne Runtimes möglich | sehr verbreitet |
Kapitel 039 · Teil 3Quarkus & MicroProfile Umsetzung im PraxisprojektQuarkus und MicroProfile verbinden Enterprise Java APIs mit cloud-nativer Laufzeit, schnellen Starts und Kubernetes-Nähe.
Rolle
Quarkus eignet sich, wenn schnelle Startup-Zeiten, Container, Kubernetes/OpenShift, geringe Speicherlast und MicroProfile-nahe APIs wichtig sind. Die Domain bleibt auch hier unabhängig.
Resource
@Path("/orders")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class QuarkusOrderResource { // Pattern: Inbound Adapter
private final PlaceOrderUseCase placeOrder;
public QuarkusOrderResource(PlaceOrderUseCase placeOrder) {
this.placeOrder = placeOrder;
}
@POST
public Response place(PlaceOrderRequest request) {
OrderId id = placeOrder.handle(request.toCommand());
return Response.accepted(new OrderResponse(id.value(), "ACCEPTED")).build();
}
}
Fault Tolerance
@ApplicationScoped
class InventoryClient implements InventoryPort { // Pattern: Adapter
@Timeout(750)
@Retry(maxRetries = 2)
@CircuitBreaker(requestVolumeThreshold = 20, failureRatio = 0.5)
public void reserve(CustomerId customerId, List<OrderLine> lines) {
// HTTP call zum Inventory-System
}
}
Config
MicroProfile Config erlaubt saubere externe Konfiguration. Keine Secrets im Code, keine Umgebungsspezifika in der Domain.
Health
Liveness prüft, ob der Prozess lebt. Readiness prüft, ob Traffic angenommen werden darf. Startup prüft lange Initialisierungen.
Trade-offs
| Vorteil | Risiko |
|---|---|
| Schneller Start und geringer Footprint | Build-/Native-Komplexität beachten |
| Kubernetes-nahe Erweiterungen | Framework-spezifische Extension-Welt |
| MicroProfile Standards | Nicht jede API deckt jedes Enterprise-Szenario ab |
Kapitel 040 · Teil 3Framework-/Library-Entscheidungskatalog V3Eine große Entscheidungsmatrix hilft, Framework, Library, Spezifikation und Tool sauber zu unterscheiden.
Entscheidungsmodell
Eine Library löst meist ein fokussiertes Problem. Ein Framework gibt Struktur, Laufzeitmodell und Integrationspunkte vor. Eine Spezifikation definiert Verträge, die mehrere Implementierungen erfüllen können. Ein Tool unterstützt Build, Test, Analyse oder Betrieb.
Matrix
| Name | Typ | Einsatz | Wann passend |
|---|---|---|---|
| Spring Boot | Framework | Service Runtime | Schneller produktiver Service mit großem Ökosystem |
| Jakarta EE | Spezifikation/Plattform | Standardisierte Enterprise Runtime | Portabilität und zertifizierte Standards wichtig |
| Quarkus | Framework | Cloud-native Runtime | Container, OpenShift, schneller Start |
| MicroProfile | Spezifikation | Cloud-native APIs | Health, Config, Fault Tolerance, JWT, OpenAPI |
| Micronaut | Framework | Compile-time DI/Microservices | Schneller Start, geringe Reflection |
| Hibernate ORM | Framework/ORM | Persistenz | Komplexe Objekt-Relationen und JPA |
| MapStruct | Library | Mapping | Explizites, schnelles DTO-Mapping |
| Flyway | Tool/Library | DB Migration | Lineare SQL-Migrationen |
| Liquibase | Tool/Library | DB Migration | ChangeSets, mehrere DB-Typen |
| Testcontainers | Library | Integrationstests | Echte DB/Broker im Test |
| OpenTelemetry | SDK/Standard | Observability | Traces, Metrics, Logs kontextualisieren |
| ArchUnit | Library | Architekturtests | Regeln im Build prüfen |
Regeln
- Erst Problem beschreiben, dann Technologie wählen.
- Framework-Code an den Rand legen.
- Libraries bevorzugen, wenn ein Problem eng ist.
- Bei Spezifikationen Implementierung und Versionsstand prüfen.
- Lizenz, Security und Wartbarkeit in die Entscheidung aufnehmen.
Beispiel
| Problem | Empfehlung | Begründung |
|---|---|---|
| Viele CRUD-/API-Services | Spring Boot oder Quarkus | Produktive Runtime und Betriebsintegration |
| Standardisierte App-Server-Landschaft | Jakarta EE | CDI/JTA/JAX-RS/JPA als Standards |
| Komplexes DB Mapping | Hibernate/JPA | Bewährtes ORM, aber Fetching bewusst planen |
| Mapping DTO ⇄ Domain | MapStruct | Compile-time Mapping, keine Reflection-Magie |
Kapitel 041 · Teil 3Transaktionen & Konsistenz: Local, JTA, Saga, OutboxEnterprise-Systeme scheitern häufig nicht am Code, sondern an falschen Konsistenzannahmen.
Transaktionsarten
| Art | Beispiel | Grenze |
|---|---|---|
| Lokale DB-Transaktion | Order + Outbox in einer DB | Nur eine Datenbank |
| JTA/XA | DB + JMS in einer globalen TX | Komplex, teuer, nicht überall cloud-nativ |
| Saga | Order, Billing, Inventory separat | Eventually consistent |
| Outbox | DB-Commit und spätere Event-Publikation | Relay und Idempotenz nötig |
Outbox
Outbox speichert ein Event in derselben Transaktion wie den fachlichen Zustand. Ein separater Prozess veröffentlicht später zuverlässig.
public interface OutboxPort { // Pattern: Transactional Outbox Port
void append(DomainEvent event);
void appendAll(List<DomainEvent> events);
}
public final class OutboxRelay { // Pattern: Polling Publisher
private final OutboxStore store;
private final MessagePublisher publisher;
public void publishPending() {
for (OutboxMessage msg : store.lockNextBatch(100)) {
publisher.publish(msg.topic(), msg.payload(), msg.idempotencyKey());
store.markPublished(msg.id());
}
}
}
Saga
Eine Saga koordiniert mehrere lokale Transaktionen. Bei Fehlern wird nicht zurückgerollt wie in einer DB, sondern kompensiert.
Idempotenz
Jeder Consumer muss Mehrfachzustellung aushalten. Dafür braucht man Idempotency Keys, deduplizierende Tabellen oder fachliche natürliche Schlüssel.
Code
public final class OrderSaga { // Pattern: Saga Orchestrator
public void on(OrderPlaced event) {
try {
billing.reserveInvoice(event.orderId());
inventory.commitReservation(event.orderId());
} catch (BillingUnavailable ex) {
inventory.releaseReservation(event.orderId()); // Kompensation
orders.markPaymentPending(event.orderId());
}
}
}
Warnung
Kapitel 042 · Teil 3Legacy-Integration: SOAP, Batch, DB & FileNeue Enterprise-Java-Systeme müssen oft mit alten Systemen kommunizieren, ohne deren Modellfehler zu übernehmen.
Prinzip
Legacy-Integration braucht eine Schutzschicht. Die neue Domain darf nicht direkt WSDL-Namen, Stored-Procedure-Parameter oder alte Statuscodes übernehmen.
SOAP
Bei SOAP ist Contract-First wichtig: WSDL, XSD, Bindings und Prozessschritte werden dokumentiert. Der Adapter übersetzt SOAP-Fehler in fachliche Fehler.
public final class LegacyBillingMapper { // Pattern: Anti-Corruption Layer
LegacyInvoiceRequest toLegacyRequest(OrderId orderId, Money total) {
LegacyInvoiceRequest request = new LegacyInvoiceRequest();
request.setExternalOrderNo(orderId.value());
request.setAmountInCent(total.amount().movePointRight(2).longValueExact());
request.setCurrency(total.currency().getCurrencyCode());
return request;
}
}
Batch
Batch eignet sich für große Mengen, Wiederanlauf, fachliche Kontrollpunkte und Nachtverarbeitung. Moderne Batchjobs sollten idempotent und beobachtbar sein.
DB
Direkter Legacy-DB-Zugriff ist riskant. Besser sind stabile Views, APIs oder klar dokumentierte Stored Procedures mit Tests.
File
Dateischnittstellen brauchen Schema, Zeichensatz, Zeilenformat, Fehlerdatei, Reprocessing und Archivierung.
Mapping
| Legacy-Feld | Neues Modell | Regel |
|---|---|---|
| CUST_NR | CustomerId | Null/Leer ablehnen |
| ORD_STAT=7 | OrderStatus.CANCELLED | Mapping dokumentieren |
| AMT_CENT | Money | Currency verpflichtend |
| ERR_CD | DomainError | Technische Codes nicht durchreichen |
Kapitel 043 · Teil 3REST API Design für GroßsystemeREST APIs sind langfristige Verträge. Entscheidend sind Stabilität, Fehlerverträge, Versionierung und Konsistenz.
API als Vertrag
Eine interne API kann genauso kritisch sein wie eine öffentliche API. Breaking Changes erzeugen Abhängigkeitsschäden in anderen Teams.
Ressourcen
| Gut | Schlecht |
|---|---|
| POST /orders | POST /createOrder |
| GET /orders/{id} | GET /getOrderById |
| POST /orders/{id}/cancellation | POST /cancel |
| GET /orders?customerId=... | POST /searchOrders ohne Not |
Fehler
{
"type": "https://errors.example.com/order/invalid-state",
"title": "Order cannot be cancelled",
"status": 409,
"detail": "Order ORD-4711 is already invoiced.",
"traceId": "4e7f9a2c8d",
"code": "ORDER_ALREADY_INVOICED"
}
Versionierung
Versionierung ist kein Ersatz für Kompatibilität. Neue optionale Felder sind meist besser als harte Brüche. Entfernen ist gefährlicher als Ergänzen.
Beispiel
public record PlaceOrderRequest(
String customerId,
List<OrderLineRequest> lines,
String idempotencyKey) {
PlaceOrderCommand toCommand() {
return new PlaceOrderCommand(new CustomerId(customerId),
lines.stream().map(OrderLineRequest::toDomain).toList(),
idempotencyKey);
}
}
Checkliste
- Ist jeder Fehler maschinenlesbar?
- Gibt es eine TraceId?
- Ist Idempotenz für POST geklärt?
- Ist die OpenAPI-Beschreibung Teil des Builds?
- Gibt es Contract Tests?
Kapitel 044 · Teil 3Messaging Workflows: JMS, Kafka & OutboxMessaging macht Systeme lose gekoppelt, aber nur mit klaren Verträgen, Idempotenz und Beobachtbarkeit robust.
Arten
| Modell | Typisch | Eigenschaft |
|---|---|---|
| JMS Queue | Command/Work Queue | Ein Consumer verarbeitet |
| JMS Topic | Publish/Subscribe | Mehrere Subscriber |
| Kafka Topic | Event Stream | Partitionen, Offset, Replay |
| Outbox Table | Zuverlässige Publikation | DB und Event konsistent |
Event Design
Events brauchen fachlichen Namen, Version, Zeit, Korrelation und Idempotency Key. Technische Payloads ohne Kontext sind schwer wartbar.
public record OrderPlacedEventV1(
String eventId,
String traceId,
String orderId,
String customerId,
Instant occurredAt,
List<Line> lines) implements DomainEvent {}
Outbox
Outbox ist der Default, wenn ein DB-Zustand und ein Event zusammengehören. Direct publish im Use Case ist fast immer riskanter.
Consumer
public final class BillingOrderPlacedConsumer { // Pattern: Idempotent Consumer
public void handle(OrderPlacedEventV1 event) {
if (processedEvents.alreadyProcessed(event.eventId())) return;
billing.createDraftInvoice(event.orderId(), event.customerId());
processedEvents.markProcessed(event.eventId());
}
}
Fehler
Fehlerstrategie: Retry für temporäre Fehler, Dead Letter Queue für nicht verarbeitbare Nachrichten, Alerting bei wachsendem Lag.
Vergleich
| Kriterium | JMS | Kafka |
|---|---|---|
| Klassische Enterprise Integration | Sehr stark | Möglich, aber anderes Modell |
| Replay historischer Events | Begrenzt | Stark |
| Ordering | Queue/Session-basiert | Partition-basiert |
| Cloud-native Streams | Mittel | Sehr stark |
Kapitel 045 · Teil 3Security & Zero Trust in Enterprise JavaSecurity ist nicht nur Login. Moderne Enterprise-Systeme brauchen Identität, Rechte, Secrets, Netzwerkgrenzen, Audit und sichere Defaults.
Modell
Zero Trust bedeutet: Kein Netzwerkbereich wird automatisch vertraut. Jede Anfrage braucht Identität, Kontext, Policy und Nachvollziehbarkeit.
AuthN/AuthZ
| Begriff | Bedeutung |
|---|---|
| Authentication | Wer bist du? |
| Authorization | Was darfst du? |
| Scope | Technische Berechtigung im Token |
| Role | Rolle aus Fach-/IAM-Kontext |
| Policy | Regel mit Kontext |
Service-to-Service
Für interne Kommunikation werden mTLS, kurzlebige Tokens, Audience-Prüfung und minimale Berechtigungen benötigt.
public final class AuthorizationPolicy { // Pattern: Policy/Strategy
public boolean mayCancel(Order order, Principal principal) {
return principal.hasRole("ORDER_MANAGER") && !order.isInvoiced();
}
}
Secrets
Secrets gehören nicht in Git, nicht in Images und nicht in Logs. Sie kommen aus Secret Manager, Kubernetes/OpenShift Secrets oder Vault-ähnlichen Systemen.
Audit
Audit muss fachliche Aktion, Akteur, Zeitpunkt, Ergebnis, TraceId und relevante Ressource enthalten.
Fehler
| Fehler | Risiko |
|---|---|
| JWT ungeprüft nur decodieren | Token-Fälschung möglich |
| Rollen im Frontend erzwingen | Umgehbar |
| Secrets in application.yml | Leak über Git/Artefakt |
| Zu breite Service-Rechte | Seitwärtsbewegung bei Angriff |
Kapitel 046 · Teil 3Observability, Runbooks & BetriebEin Enterprise-System ist erst fertig, wenn Betrieb und Fehlerdiagnose mitgedacht sind.
Signale
| Signal | Antwortet auf |
|---|---|
| Logs | Was ist im Prozess passiert? |
| Metrics | Wie verhält sich das System quantitativ? |
| Traces | Wo ging Zeit oder Fehler über Systemgrenzen verloren? |
| Events/Audit | Welche fachliche Tatsache wurde erzeugt? |
Trace
TraceId und CorrelationId müssen durch REST, Messaging, Batch und SOAP weitergegeben werden.
public final class TraceContext { // Pattern: Context Object
private final String traceId;
private final String correlationId;
public Map<String, String> asHeaders() {
return Map.of("X-Trace-Id", traceId, "X-Correlation-Id", correlationId);
}
}
Metriken
- Order creation rate
- Billing error rate
- Outbox backlog
- Consumer lag
- HTTP latency p95/p99
- DB pool exhaustion
Logs
Logs sind strukturiert, maschinenlesbar und enthalten keine Secrets. Stacktraces ohne Kontext reichen nicht.
Runbook
| Störung | Prüfen | Aktion |
|---|---|---|
| Outbox wächst | DB Lock, Broker erreichbar, Relay Logs | Relay skalieren oder fehlerhafte Nachricht isolieren |
| Billing Fehler 5xx | Trace, SOAP Endpoint, Timeout | Circuit Breaker öffnen lassen, Retry prüfen |
| Readiness false | DB/Broker/Config | Traffic stoppen, Ursache beheben |
SLO
Ein gutes SLO ist fachlich: 99,5% der Bestellungen werden innerhalb von 2 Sekunden angenommen; 99,9% der Outbox-Events werden innerhalb von 60 Sekunden publiziert.
Kapitel 047 · Teil 3Testing: Unit, Integration, Contract & E2ETests müssen zur Architektur passen: schnell in der Mitte, realistisch an den Rändern, wenige aber wertvolle E2E-Flows.
Strategie
Die Testpyramide wird im Enterprise-Kontext oft falsch verstanden. Viele langsame E2E-Tests ersetzen keine guten Domain- und Use-Case-Tests.
Unit
@Test
void orderWithoutLinesIsRejected() {
assertThrows(DomainRuleViolation.class,
() -> Order.place(new CustomerId("C-1"), List.of()));
}
Integration
Integrationstests prüfen Adapter gegen echte Infrastruktur: PostgreSQL, Kafka, JMS-kompatible Broker, HTTP WireMock oder Testcontainers.
Contract
Contract Tests verhindern, dass Producer und Consumer beim API-/Event-Vertrag auseinanderlaufen.
E2E
E2E ist teuer und fragil. Deshalb nur wenige kritische Happy Paths und ausgewählte Fehlerpfade.
Architekturtests
@AnalyzeClasses(packages = "com.aydinsude.enterprise")
class ArchitectureRulesTest {
@ArchTest
static final ArchRule domain_has_no_framework_dependency =
noClasses().that().resideInAPackage("..domain..").should()
.dependOnClassesThat().resideInAnyPackage("org.springframework..", "jakarta..", "org.hibernate..");
}
Kapitel 048 · Teil 3Deployment: VM, Bare Metal, Kubernetes & OpenShiftEnterprise Java muss verschiedene Betriebsumgebungen erklären können: VM, Bare Metal, Kubernetes und OpenShift.
Vergleich
| Ziel | Vorteil | Risiko |
|---|---|---|
| VM | Bekannt, stabil, guter Einstieg | Manuelles Scaling, driftende Konfiguration |
| Bare Metal | Volle Kontrolle, Performance | Betriebsaufwand hoch |
| Kubernetes | Portabilität, Orchestrierung | Komplexität, Plattformwissen nötig |
| OpenShift | Enterprise-Plattform, Security, Operators | Lizenz/Plattformbetrieb einplanen |
VM
VMs eignen sich für klassische Enterprise-Deployments, Migrationen und Systeme mit niedriger Änderungsrate.
Bare Metal
Bare Metal ist sinnvoll, wenn Hardwarekontrolle, spezielle Latenz oder Kosteneffizienz bei hoher Auslastung wichtig sind.
Kubernetes
Kubernetes bringt Scheduling, Service Discovery, Self-Healing, Secrets, ConfigMaps und Rollouts.
OpenShift
OpenShift ergänzt Kubernetes um Enterprise-Funktionen wie Security-Konventionen, Routes, Build/Deployment-Integration, Operatoren und Plattform-Governance.
Strategie
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
template:
spec:
containers:
- name: order-service
image: registry.example.com/order-service:1.0.0
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
resources:
requests:
cpu: "250m"
memory: "512Mi"
Kapitel 049 · Teil 3Refactoring Before/After KatalogRefactoring wird greifbar, wenn man Ausgangscode und Zielcode nebeneinander sieht.
Vorgehen
- Ist-Verhalten messen.
- Tests um kritische Pfade legen.
- Fachlichen Slice wählen.
- Use Case extrahieren.
- Ports einführen.
- Adapter nacheinander ersetzen.
Monster Service
public void createOrder(Map<String, Object> input) {
// schlecht: Validierung, SQL, SOAP, Statuslogik und Eventing in einer Methode
if (input.get("customer") == null) throw new RuntimeException("missing");
jdbc.update("insert into orders ...");
soapClient.reserveInvoice(input);
jms.send("ORDER_CREATED", input);
}
public OrderId handle(PlaceOrderCommand command) {
return tx.required(() -> {
Order order = Order.place(command.customerId(), command.lines());
orders.save(order);
outbox.appendAll(order.pullEvents());
return order.id();
});
}
JDBC Spaghetti
SQL darf im Adapter bleiben, aber nicht die Domain-Sprache ersetzen. Repository-Methoden sollen fachlich lesbar sein.
Mapping
Manuelles Ad-hoc-Mapping quer durch Services erzeugt Fehler. MapStruct oder explizite Mapper bündeln die Übersetzung.
Exception Handling
| Vorher | Nachher |
|---|---|
| RuntimeException ohne Code | DomainError + HTTP Problem Detail |
| Stacktrace im Response | TraceId + maschinenlesbarer Fehlercode |
| Fehler verschlucken | Retry/DLQ/Audit nach Fehlerart |
Check
Kapitel 050 · Teil 3Senior-Checklisten, Lernplan & PrüfungDieses Abschlusskapitel fasst V3 als prüfbaren Senior-Lernpfad zusammen.
Senior Checkliste
| Bereich | Prüffrage |
|---|---|
| Domain | Sind Invarianten im Modell oder verstreut in Services? |
| Architektur | Kann Domain ohne Framework getestet werden? |
| Transaktionen | Ist Konsistenz pro Use Case dokumentiert? |
| Integration | Gibt es ACL für Legacy-Systeme? |
| Security | Sind AuthZ, Secrets und Audit geklärt? |
| Betrieb | Gibt es SLOs, Runbooks und Traces? |
| Test | Sind Unit, Integration, Contract und E2E sinnvoll verteilt? |
Lernplan
| Woche | Fokus | Ergebnis |
|---|---|---|
| 1 | Domain und Use Cases | Order-Domain ohne Framework |
| 2 | Ports und Adapter | Repository, Billing, Inventory Ports |
| 3 | Spring/Jakarta/Quarkus Vergleich | Drei Adaptervarianten verstehen |
| 4 | Transaktionen und Outbox | Konsistenzstrategie dokumentieren |
| 5 | Security und Observability | Runbook und Trace-Konzept |
| 6 | Testing und Deployment | CI-Gates und Deployment-Manifeste |
Review-Fragen
- Warum ist Outbox sicherer als direkter Event-Publish im Use Case?
- Wann ist JTA sinnvoll und wann Saga?
- Welche Abhängigkeiten darf die Domain nicht importieren?
- Wie unterscheiden sich Framework, Library, Spezifikation und Tool?
- Welche Metrik zeigt, dass die Outbox nicht hinterherkommt?
Praxisaufgaben
- Baue einen neuen Adapter für ein Payment-System.
- Schreibe einen Contract Test für
OrderPlacedEventV1. - Ersetze einen direkten SOAP-Call durch Port + Adapter + ACL.
- Dokumentiere ein neues Pattern in
docs/design-patterns.md. - Erstelle ein Runbook für steigenden Consumer Lag.
Abschluss
V3 ist als Lernbuch, Nachschlagewerk und Projektbasis gedacht: lesen, ausprobieren, im Code markieren, im Team diskutieren und als Vorlage für echte Modernisierung verwenden.
Senior-Architektur & Migration
Order-to-Cash, DDD, Fehlerarchitektur, Idempotenz, CQRS, OpenShift, Migration und Interviewtraining.
Kapitel 051 · Teil 4Order-to-Cash End-to-End Case StudyEnd-to-end Ablauf vom Portal bis Buchhaltung, inklusive fachlicher Zuständigkeiten, Schnittstellen, Fehlerfällen und Betriebsnachweisen.
Fachlicher Ablauf
Order-to-Cash beginnt nicht im Controller, sondern bei einer fachlichen Absicht: Ein Kunde will etwas bestellen. Danach folgen Preisprüfung, Limitprüfung, Bestandsreservierung, Rechnungslogik, Event-Publish und Betriebsnachweis. In Enterprise-Projekten ist wichtig, jeden Schritt einem System Owner und einer Transaktionsgrenze zuzuordnen.
Technischer Schnitt
Der rote Faden in V6 ist ein Vertikalschnitt. Jede Schicht bekommt nur die Verantwortung, die sie tragen kann: Portal/BFF für Darstellung, Application Service für Use Case, Domain für Invarianten, Adapter für Fremdsysteme, Outbox für technische Übergabe.
Beispielcode
package at.aydinsude.enterprise.order.application; import at.aydinsude.enterprise.order.domain.*; import java.time.Clock; // Pattern: Application Service - orchestriert genau einen fachlichen Use Case. // Pattern: Port-and-Adapter - nutzt RepositoryPort und EventPublisherPort statt Framework-Abhängigkeiten. public final class PlaceOrderUseCase { private final OrderRepositoryPort orders; private final CustomerRiskPort customerRisk; private final EventPublisherPort events; private final Clock clock; public PlaceOrderUseCase(OrderRepositoryPort orders, CustomerRiskPort customerRisk, EventPublisherPort events, Clock clock) { this.orders = orders; this.customerRisk = customerRisk; this.events = events; this.clock = clock; } public OrderId handle(PlaceOrderCommand command) { if (orders.existsByIdempotencyKey(command.idempotencyKey())) { return orders.findOrderIdByIdempotencyKey(command.idempotencyKey()); } customerRisk.assertCustomerMayOrder(command.customerId(), command.total()); Order order = Order.place(command.customerId(), command.lines(), command.idempotencyKey(), clock.instant()); orders.save(order); events.publishAll(order.pullDomainEvents()); return order.id(); } }
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 052 · Teil 4DDD Tactical Modeling im Java Enterprise ProjektAggregates, Entities, Value Objects, Domain Events und Repositories als taktisches Modell für robuste Enterprise-Domänen.
Aggregate statt Datencontainer
Ein Aggregate schützt eine Konsistenzgrenze. Es ist nicht einfach eine JPA-Entity mit Gettern und Settern. Im Order-Aggregate liegen Regeln wie Mindestmenge, Statusübergänge, Kreditlimit-Reaktion und Domain Events.
Value Objects
Value Objects wie Money, Quantity und CustomerId sind bewusst klein, unveränderlich und fachlich benannt. Dadurch verschwinden viele primitive String-/BigDecimal-Fehler.
DDD-Checkliste
| Element | Zweck | Java-Umsetzung |
|---|---|---|
| Aggregate | Konsistenzgrenze | Klasse mit Methoden statt Setter |
| Value Object | Fachwert ohne Identität | record oder final class |
| Domain Event | Geschehenes Ereignis | record OrderPlaced(...) |
| Repository Port | Persistenzabsicht | Interface im Domain/Application-Rand |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 053 · Teil 4Fehlerarchitektur, Problem Details und Exception MappingFachliche Fehler, technische Fehler, HTTP Problem Details, SOAP Faults und stabile Fehlerverträge im Großsystem.
Fehlerarten trennen
Ein fachlicher Konflikt ist kein technischer Systemfehler. Wenn ein Kunde kein Limit hat, ist das etwas anderes als ein Datenbank-Timeout. Diese Trennung muss sich in Code, API-Vertrag, Logging und Monitoring zeigen.
Problem Details
REST-APIs sollten stabile Fehlercodes und maschinenlesbare Details liefern. SOAP-Systeme brauchen entsprechende Fault-Strukturen. Wichtig ist, dass interne Klassennamen nicht nach außen leaken.
Beispielcode
package at.aydinsude.enterprise.api; import java.net.URI; import java.util.Map; // Pattern: Error Contract - technische Darstellung ist stabil, Domain bleibt unabhängig. public record ProblemDetails( URI type, String title, int status, String detail, String instance, Map<String, Object> extensions) { public static ProblemDetails businessConflict(String code, String detail, String traceId) { return new ProblemDetails( URI.create("https://errors.example.com/enterprise/" + code), "Business conflict", 409, detail, traceId, Map.of("code", code, "retryable", false)); } }
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 054 · Teil 4Idempotenz, Exactly-Once-Illusion und WiederholbarkeitWarum Enterprise-Systeme Wiederholung als Normalfall behandeln müssen: Idempotency Keys, deduplication, Outbox und Replay.
Warum Exactly Once meist eine Illusion ist
Netzwerke, Broker und Datenbanken liefern selten Ende-zu-Ende-Exactly-Once über alle Grenzen. Robuste Enterprise-Systeme bauen deshalb auf mindestens-einmal-Zustellung plus Idempotenz, Deduplication und Reconciliation.
Idempotency Key
Der Idempotency Key gehört zu einem fachlichen Kontext: Kunde, Operation, Zeitraum und Payload-Fingerprint. Derselbe Schlüssel mit anderer Payload muss als Missbrauch oder Clientfehler behandelt werden.
Beispielcode
package at.aydinsude.enterprise.order.application; import java.time.Instant; import java.util.Optional; // Pattern: Idempotent Consumer - Wiederholung ist erwartet, nicht außergewöhnlich. public final class IdempotencyService { private final IdempotencyStore store; public IdempotencyService(IdempotencyStore store) { this.store = store; } public <T> T executeOnce(String key, Class<T> resultType, java.util.function.Supplier<T> action) { Optional<T> previous = store.findSuccessfulResult(key, resultType); if (previous.isPresent()) { return previous.get(); } store.markStarted(key, Instant.now()); try { T result = action.get(); store.markSucceeded(key, result, Instant.now()); return result; } catch (RuntimeException ex) { store.markFailed(key, ex.getClass().getSimpleName(), Instant.now()); throw ex; } } }
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 055 · Teil 4Persistenz Advanced: Locking, Audit, Soft Delete und HistorisierungOptimistic Locking, pessimistische Sperren, Audit-Spalten, technische Historisierung und fachliche Nachvollziehbarkeit.
Optimistic Locking
Optimistic Locking passt, wenn Konflikte selten sind und Benutzer oder Prozesse wiederholen können. Die Version-Spalte schützt vor Lost Updates.
Audit und Historie
Audit-Spalten beantworten technische Fragen. Fachliche Historie beantwortet Business-Fragen. Beide sollten nicht verwechselt werden.
Entscheidungstabelle
| Mechanismus | Wann verwenden? | Risiko |
|---|---|---|
| Optimistic Lock | seltene Konflikte | Retry/Conflict UX nötig |
| Pessimistic Lock | kurze kritische Sequenz | Deadlocks/Throughput |
| Soft Delete | rechtlich/fachlich nötig | Filterfehler |
| History Table | Nachvollziehbarkeit | Datenvolumen |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 056 · Teil 4Datenbankmigration mit Flyway und LiquibaseSchema-Versionierung, Rollback-Denken, expand/contract Migrationen und Datenkorrekturen ohne Produktionsstillstand.
Expand/Contract
Produktionsmigrationen sollten kompatibel ausgerollt werden. Erst erweitern, dann Code umstellen, dann alte Struktur entfernen.
Flyway vs Liquibase
Flyway ist besonders einfach für lineare SQL-Versionen. Liquibase ist stark bei deklarativen Changesets und komplexeren Deployment-Prozessen. Entscheidend ist weniger das Tool als die Disziplin im Prozess.
Migrationsbeispiel
-- V20260707_01__add_order_audit.sql ALTER TABLE orders ADD COLUMN created_by VARCHAR(120); ALTER TABLE orders ADD COLUMN trace_id VARCHAR(80); UPDATE orders SET created_by = 'migration', trace_id = 'baseline' WHERE created_by IS NULL; ALTER TABLE orders ALTER COLUMN created_by SET NOT NULL;
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 057 · Teil 4CQRS, Read Models, Search und ReportingSchreibmodell sauber halten, Lesemodelle gezielt aufbauen, Suche und Reporting entkoppeln.
Write Model schützen
CQRS bedeutet nicht automatisch Event Sourcing. Oft reicht es, ein sauberes Write Model mit separaten Read Models für Suche, Listen und Reporting zu kombinieren.
Read Model Rebuild
Ein gutes Lesemodell kann neu aufgebaut werden. Deshalb braucht es Projektion, Rebuild-Prozess, Versionierung und Messung von Lag.
Matrix
| Use Case | Modell | Hinweis |
|---|---|---|
| Bestellung anlegen | Write Model | Transaktion + Invarianten |
| Bestellliste filtern | Read Model | denormalisiert |
| Volltextsuche | Search Index | asynchron aktualisiert |
| Monatsreport | Reporting Store | nicht aus OLTP erzwingen |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 058 · Teil 4Modularer Monolith und Spring ModulithWarum ein gut geschnittener Modular Monolith oft der bessere Zwischenschritt vor Microservices ist.
Warum modularer Monolith
Ein Modular Monolith hält Deployment einfach, erzwingt aber fachliche Grenzen. Für viele Modernisierungen ist er der beste Schritt zwischen Legacy-Monolith und verteilten Microservices.
Spring Modulith Idee
Module werden sichtbar, Abhängigkeiten prüfbar und Ereignisse innerhalb des Monolithen besser modelliert.
Architekturtest
package at.aydinsude.enterprise.architecture; import com.tngtech.archunit.core.importer.ClassFileImporter; import com.tngtech.archunit.lang.syntax.ArchRuleDefinition; // Pattern: Fitness Function - Architekturregel als automatisierter Test. class ModuleBoundaryTest { void domainMustNotDependOnAdapters() { var classes = new ClassFileImporter().importPackages("at.aydinsude.enterprise"); ArchRuleDefinition.noClasses() .that().resideInAPackage("..domain..") .should().dependOnClassesThat().resideInAPackage("..adapter..") .check(classes); } }
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 059 · Teil 4Jakarta Data, Repository Pattern und PortabilitätJakarta Data als Standardisierungsschritt, Repository-Abstraktion und portabler Umgang mit Persistenz.
Repository nicht mit CRUD verwechseln
Ein Repository ist fachlich motiviert. Es speichert und lädt Aggregates oder Projektionen. Eine generische CRUD-Schnittstelle ist in komplexen Domänen oft zu schwach.
Jakarta Data
Jakarta Data standardisiert Repository-ähnliche Persistenzkonzepte innerhalb der Jakarta-EE-Welt. V6 behandelt es als Standardisierungsoption, nicht als Zwang für jede Architektur.
Portabilität
Portabilität entsteht nicht nur durch APIs, sondern durch disziplinierte Grenzen: Domain kennt keine Provider-Annotationen, Queries sind gekapselt, Integrationsverträge sind getestet.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 060 · Teil 4Quarkus Native, JVM Mode und Startup-StrategienQuarkus im JVM- und Native-Modus, Build-Time-Metadaten, Container-Images und Betriebsentscheidungen.
JVM Mode vs Native
JVM Mode ist oft die beste Wahl für Entwicklung, Debugging und maximale Kompatibilität. Native Mode kann bei Startup und Footprint helfen, verlangt aber konsequente Tests mit echten Extensions.
Build-Time Ansatz
Quarkus verschiebt viel Arbeit in die Build-Zeit. Das ist stark für Container, aber man muss verstehen, welche Reflection, Proxies und Ressourcen im Native Image verfügbar sind.
Betriebsentscheidung
| Kriterium | JVM Mode | Native Mode |
|---|---|---|
| Startzeit | gut | sehr gut |
| Memory Footprint | mittel | oft niedriger |
| Debugging | sehr vertraut | spezifischer |
| Kompatibilität | breiter | prüfen |
| CI-Zeit | kürzer | länger |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 061 · Teil 4Virtual Threads, Thread Pools und Blocking IOVirtual Threads sinnvoll einsetzen, klassische Pools verstehen und Blocking/Nonblocking sauber unterscheiden.
Grundregel
Virtual Threads machen blockierenden Code skalierbarer, aber sie vergrößern nicht automatisch Datenbankpools, Broker-Limits oder Remote-System-Kapazität.
Typischer Fehler
Ein Team erhöht parallele Requests massiv, aber lässt den DB-Pool bei 20 Verbindungen. Ergebnis: Warteschlangen wandern nur an eine andere Stelle.
Beispiel
try (var executor = java.util.concurrent.Executors.newVirtualThreadPerTaskExecutor()) { var futures = customerIds.stream() .map(id -> executor.submit(() -> customerClient.loadCustomer(id))) .toList(); for (var future : futures) { handle(future.get()); } } // Wichtig: Remote-Limits, Timeouts und Bulkheads bleiben erforderlich.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 062 · Teil 4Reactive vs Imperative Enterprise JavaWann reaktive Programmierung hilft, wann sie nur Komplexität erzeugt und wie man beide Modelle bewertet.
Imperativ ist nicht altmodisch
Die meisten CRUD- und Use-Case-Flows sind imperativ besser lesbar. Reactive lohnt sich besonders bei Streams, Backpressure und sehr hoher IO-Konkurrenz.
Grenzen ziehen
Eine reaktive Transportstrecke darf nicht die Domain verkomplizieren. Der Kern kann synchron und klar bleiben, während Adapter reactive arbeiten.
Entscheidung
| Frage | Imperativ | Reactive |
|---|---|---|
| Team-Erfahrung | leicht | höherer Lernbedarf |
| Backpressure nötig? | nein | ja |
| Debugging | einfacher | anspruchsvoller |
| Domain-Logik | sehr passend | nur mit Disziplin |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 063 · Teil 4API Gateway, BFF und Enterprise Portal IntegrationGateway, Backend-for-Frontend, Portal, Session-Kontext, Token Relay und Anti-Corruption Layer.
BFF als UI-Adapter
Ein Backend-for-Frontend aggregiert Daten für eine konkrete Oberfläche. Es sollte keine zentrale Fachlogik übernehmen, sonst entsteht ein neuer Monolith am Rand.
Gateway ist Infrastruktur
Gateway-Funktionen sind Routing, TLS, Rate Limit, AuthN-Vorprüfung und Traffic Policies. Es ersetzt keine fachliche Autorisierung im Service.
Portal-Integration
Bei Portalen ist Kontext wichtig: Benutzer, Mandant, Rolle, Session, Sprache, Consent und Audit müssen über Systemgrenzen nachvollziehbar bleiben.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 064 · Teil 4Orchestrierung, Choreografie und Saga DesignWorkflow-Design mit zentralem Orchestrator oder dezentraler Choreografie, inklusive Kompensationen.
Orchestrierung
Ein Orchestrator macht Prozesszustand sichtbar und eignet sich für lange, regelreiche Abläufe. Dafür entsteht eine zentrale Komponente.
Choreografie
Choreografie koppelt weniger zentral, kann aber schwerer zu debuggen sein. Ohne gute Observability wird sie schnell unverständlich.
Kompensation
Eine Saga rollt nicht technisch zurück. Sie führt fachliche Gegenaktionen aus, zum Beispiel Reservierung freigeben oder Rechnung stornieren.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 065 · Teil 4File-, SFTP-, CSV- und EDI-IntegrationEnterprise-Integration ist nicht nur REST: Dateien, SFTP, CSV, EDI, Quarantäne und Reprocessing.
Dateien bleiben Enterprise-Realität
Viele Systeme liefern weiterhin CSV, Fixed Width, EDI oder XML per SFTP. Moderne Architektur muss diese Welt kapseln, nicht ignorieren.
Quarantäne
Fehlerhafte Dateien dürfen nicht verschwinden. Sie brauchen Quarantäne, Fehlerbericht, manuelles oder automatisches Reprocessing und Audit.
Importfluss
landing/ inbound/ORDERS_20260707_001.csv processing/ORDERS_20260707_001.csv quarantine/ORDERS_20260707_001.error.json archive/2026/07/07/ORDERS_20260707_001.csv Jeder Statuswechsel wird mit Checksumme, TraceId und fachlicher BatchId dokumentiert.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 066 · Teil 4Enterprise Reporting, Export und Batch-FensterGroße Reports, Exporte, Nachtläufe, Datenfenster, Wiederanlauf und fachlicher Abgleich.
Batch-Fenster
Batchjobs haben fachliche Zeitfenster. Ein Nachtlauf darf nicht blind Daten lesen, während der Tagbetrieb dieselben Daten verändert.
Restartability
Ein Batch muss wiederanlaufbar sein. Chunk-Größe, Checkpoint, Idempotenz und fachliche Abstimmung entscheiden über Stabilität.
Reporting
Große Reports gehören nicht unkontrolliert auf die OLTP-Datenbank. Read Replicas, Snapshots oder Reporting Stores schützen den Kernbetrieb.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 067 · Teil 4Security Production: Keycloak, mTLS, Secrets und AuditProduktionsnahe Security-Architektur mit Identity Provider, mTLS, Secret Rotation, Audit Trail und Least Privilege.
Produktionsnahe Security
Security besteht nicht nur aus Login. Relevant sind Identity Provider, Service-zu-Service-Vertrauen, Secret Rotation, Audit, Policy Enforcement und Incident Response.
mTLS und Token
mTLS beantwortet, welcher Dienst spricht. Token beantwortet, in welchem Benutzer-/Clientkontext gehandelt wird. Beides ersetzt einander nicht.
Audit Trail
Ein guter Audit Trail dokumentiert fachliche Aktion, technische Identität, Benutzerkontext, Zeitpunkt, Ergebnis und Korrelation.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 068 · Teil 4Dependency Management, BOMs und Version GovernanceBOMs, Parent-POMs, Dependency Constraints, Plugin Management und Upgrade-Kontrolle im Enterprise-Team.
Version Governance
Ohne zentrale Version Governance entstehen verschiedene Spring-, Jackson-, Netty-, Hibernate- und Plugin-Stände im selben Unternehmen. Das macht Security Fixes langsam.
BOM und Plugin Management
BOMs steuern Bibliotheksversionen. Plugin Management steuert Build-Verhalten. Beides gehört in einen nachvollziehbaren Parent oder Build-Standard.
POM-Auszug
<project> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>${maven.enforcer.version}</version> </plugin> </plugins> </pluginManagement> </build> </project>
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 069 · Teil 4Supply Chain Security, SBOM und LizenzrisikenSBOM, CVE-Prozess, Lizenzprüfung, Reproduzierbarkeit und sichere Artefaktkette.
SBOM
Eine Software Bill of Materials macht Abhängigkeiten maschinenlesbar. Sie ist Grundlage für CVE-Abgleich, Lizenzprüfung und Lieferkettennachweise.
Lizenzrisiko
Nicht jede Open-Source-Lizenz passt zu jedem Produktmodell. Copyleft, Netzwerk-Copyleft, Notice-Pflichten und transitive Abhängigkeiten müssen geprüft werden.
Pipeline-Evidence
Build-Logs, SBOM, Signatur, Testreport und Freigabeentscheidung sollten als Liefernachweis archiviert werden.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 070 · Teil 4CI/CD Pipelines mit Jenkins, GitHub Actions und TektonBuild-Pipelines, Qualitätsgates, Artefaktpromotion, Umgebungen und Deployment-Automatisierung.
Pipeline-Stufen
Eine gute Pipeline kompiliert nicht nur. Sie prüft Architektur, Tests, Security, Lizenz, SBOM, Container-Scan, Deployment und Smoke Tests.
Promotion statt Rebuild
Ein Artefakt sollte durch Umgebungen promotet werden. Für Stage und Prod neu zu bauen erzeugt schwer nachvollziehbare Unterschiede.
CI Beispiel
name: enterprise-java-ci on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-java@v4 with: distribution: temurin java-version: '25' cache: maven - run: ./mvnw -B -DskipITs=false verify - run: ./mvnw -B cyclonedx:makeAggregateBom - run: ./mvnw -B org.owasp:dependency-check-maven:check
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 071 · Teil 4OpenShift Produktionsarchitektur für Java EnterpriseNamespaces, Routes, Services, DeploymentConfig/Deployment, ConfigMaps, Secrets, HPA und Betriebsgrenzen.
Produktionsschnitt
OpenShift ist nicht nur ein Ort für Pods. Entscheidend sind Namespaces, Ressourcenlimits, Probes, Routes, Secrets, Network Policies, Operators und Betriebsprozesse.
Java im Container
Heap, Metaspace, Threadanzahl, CPU Limits und GC müssen zusammen betrachtet werden. Falsche Limits erzeugen OOMKills oder schlechte Latenz.
Deployment
apiVersion: apps/v1 kind: Deployment metadata: name: order-service spec: replicas: 3 selector: matchLabels: { app: order-service } template: metadata: labels: { app: order-service } spec: containers: - name: app image: registry.example.com/order-service:1.0.0 ports: [{ containerPort: 8080 }] envFrom: - configMapRef: { name: order-service-config } - secretRef: { name: order-service-secrets } readinessProbe: httpGet: { path: /actuator/health/readiness, port: 8080 } livenessProbe: httpGet: { path: /actuator/health/liveness, port: 8080 } resources: requests: { cpu: "250m", memory: "512Mi" } limits: { cpu: "1000m", memory: "1024Mi" }
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 072 · Teil 4SLOs, Incident Response und Runbook-SzenarienVon Metriken zu Entscheidungen: SLO, Error Budget, Burn Rate, Incident-Triage und Postmortem.
SLI und SLO
Ein SLI misst ein relevantes Symptom. Ein SLO setzt das Ziel. Error Budget macht sichtbar, wie viel Risiko für Änderungen verfügbar ist.
Incident Triage
Bei Störungen zählt zuerst Impact: Wer ist betroffen, wie stark, seit wann, gibt es Workaround und wer entscheidet über Rollback?
Runbook-Fragen
| Frage | Beispiel |
|---|---|
| Ist es ein Symptom-Alert? | Checkout Error Rate > 2% |
| Welche Metrik begrenzt? | DB Pool Wait Time |
| Was ist erste Mitigation? | Traffic reduzieren, Feature Flag aus |
| Wer ist Owner? | Order Platform On-Call |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 073 · Teil 4Testing Labs: Testcontainers, Contract Tests und ChaosRealistische Test-Labs mit Datenbank, Message Broker, Consumer Contracts, WireMock und Fehler-Injektion.
Testcontainers Lab
Integrationstests gegen echte Datenbanken und Broker finden Fehler, die Mocks nicht sehen: SQL-Dialekt, Transaktionen, Serialization, Consumer Lag.
Contract Tests
Consumer Contracts verhindern, dass Provider Änderungen ausrollt, die Clients brechen. Sie sind besonders wertvoll bei Portal/BFF/API-Landschaften.
Chaos im Kleinen
Timeouts, 500er, Deadlocks, Broker-Neustarts und langsame Antworten sollten kontrolliert im Test-Lab vorkommen.
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 074 · Teil 4Migration Playbook: WebSphere EAR zu Cloud NativeSchrittweise Migration von EAR/WAR/EJB/SOAP/JMS/JSP zu modularen Java-Services auf Container-Plattformen.
Inventory der Altlast
Vor Migration werden Module, Deployments, EJBs, SOAP-Operationen, JMS-Queues, Datenbankzugriffe, JSP-Seiten, Batchjobs und Betriebsjobs inventarisiert.
Strangler
Nicht alles wird neu geschrieben. Neue Vertikalschnitte übernehmen gezielt Traffic, während Legacy-Systeme über Adapter weiterlaufen.
Cutover-Kriterien
| Kriterium | Nachweis |
|---|---|
| Fachgleichheit | Parallel Run Abgleich |
| Performance | Lasttest mit produktnahen Daten |
| Security | OIDC/mTLS/Secrets geprüft |
| Betrieb | Runbook + Alerts |
| Rollback | Route/Feature Flag zurückschaltbar |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Kapitel 075 · Teil 4Senior Architekturprüfung und InterviewfragenFragen, Aufgaben und Bewertungsraster für echte Senior-Gespräche, Reviews und Projektentscheidungen.
Prüfungslogik
Senior-Niveau bedeutet nicht, alle Framework-APIs auswendig zu kennen. Wichtig ist, Trade-offs zu erkennen, Grenzen zu ziehen, Risiken zu dokumentieren und Code als Beweis zu liefern.
Interviewfragen
Warum Saga statt JTA? Wann Modular Monolith statt Microservices? Wie verhindert man doppelte Events? Wie migriert man ein SOAP-Portal ohne Big Bang? Wie erkennt man, dass eine Architekturentscheidung funktioniert?
Bewertungsraster
| Stufe | Merkmal |
|---|---|
| Junior | kann Framework verwenden |
| Professional | kann Use Cases sauber implementieren |
| Senior | kann Grenzen, Risiken und Betrieb erklären |
| Lead | kann Organisation, Migration und Governance steuern |
Praxisübertragung auf das V4-Beispielprojekt
Entscheidung
Dokumentiere die getroffene Architekturentscheidung als ADR, inklusive Alternativen, Folgen und Betriebsrisiken.
Code-Nachweis
Markiere verwendete Entwurfsmuster direkt im Code und ergänze sie in docs/design-patterns.md.
Betrieb
Definiere Metrik, Alert, Runbook-Schritt und Rollback-Option für diesen Bereich.
Typische Fehlerbilder
- Framework-Feature wird eingesetzt, ohne fachliche Grenze zu verstehen.
- Technische Wiederholung wird nicht idempotent gemacht.
- Observability wird erst nach Produktionsproblem ergänzt.
- Tests prüfen nur Happy Path und keine Wiederanläufe.
Produktion, Governance & Betriebsreife
Reference Architecture, Multi-Tenancy, Event-Versionierung, API Lifecycle, Performance, DR, Compliance und Platform Engineering.
Kapitel 076 · Teil 5Enterprise Reference Architecture MapEin Gesamtbild für produktionsreife Java-Enterprise-Landschaften: Domäne, Integrationen, Daten, Plattform, Security, Observability und Governance werden als zusammenhängende Karte verstanden.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Enterprise Reference Architecture Map als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Enterprise Reference Architecture Map sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ReferenceArchitectureMap { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# enterprise-reference-architecture-map.yaml owner: enterprise-architecture chapter: 76 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 077 · Teil 5Architecture Governance, Fitness Functions und ADR BetriebWie Architekturentscheidungen lebendig bleiben: ADRs, Fitness Functions, Review-Rhythmen, Ausnahmeprozesse und messbare Architekturregeln.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Architecture Governance, Fitness Functions und ADR Betrieb als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Architecture Governance, Fitness Functions und ADR Betrieb sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ArchitectureFitnessFunction { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# architecture-governance-fitness-functions-und-adr-betrieb.yaml owner: enterprise-architecture chapter: 77 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 078 · Teil 5Multi-Tenancy und MandantenisolationMandantenfähigkeit in Java-Enterprise-Systemen: Tenant-Kontext, Datenisolation, Sicherheit, Migrationen, Observability und Betriebsrisiken.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Multi-Tenancy und Mandantenisolation als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Multi-Tenancy und Mandantenisolation sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class TenantContextPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# multi-tenancy-und-mandantenisolation.yaml owner: enterprise-architecture chapter: 78 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 079 · Teil 5Data Ownership und IntegrationsgrenzenWelche Daten gehören welchem System? Ownership, Kopien, Referenzen, Synchronisation, Reporting und Anti-Corruption-Layer werden sauber abgegrenzt.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Data Ownership und Integrationsgrenzen als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Data Ownership und Integrationsgrenzen sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class DataOwnershipRule { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# data-ownership-und-integrationsgrenzen.yaml owner: enterprise-architecture chapter: 79 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 080 · Teil 5Event-Versionierung, Schema Registry und KompatibilitätEvents müssen jahrelang lesbar bleiben: Versionierung, evolutionäre Schemas, Consumer-Kompatibilität, Replay und Deprecation.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Event-Versionierung, Schema Registry und Kompatibilität als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Event-Versionierung, Schema Registry und Kompatibilität sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class EventCompatibilityPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# event-versionierung-schema-registry-und-kompatibilitaet.yaml owner: enterprise-architecture chapter: 80 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 081 · Teil 5Kafka, JMS und Business-Idempotenz im VergleichMessaging ist nicht automatisch fachlich konsistent: Broker-Garantien, Transaktionen, Ordering, Duplicate Handling und fachliche Idempotenz im Vergleich.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Kafka, JMS und Business-Idempotenz im Vergleich als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Kafka, JMS und Business-Idempotenz im Vergleich sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class BrokerGuaranteeMatrix { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# kafka-jms-und-business-idempotenz-im-vergleich.yaml owner: enterprise-architecture chapter: 81 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 082 · Teil 5Transactional Messaging Lab: Outbox, Inbox und Dead LetterEin praxisnahes Lab für zuverlässige Nachrichtenverarbeitung mit Outbox, Inbox, Retry, DLQ, Reprocessing und Nachweisbarkeit.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Transactional Messaging Lab: Outbox, Inbox und Dead Letter als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Transactional Messaging Lab: Outbox, Inbox und Dead Letter sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class TransactionalMessagingLab { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# transactional-messaging-lab-outbox-inbox-und-dead-letter.yaml owner: enterprise-architecture chapter: 82 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 083 · Teil 5Workflow Engines und Prozessautomation in JavaWann BPMN/Workflow-Engines helfen und wann ein einfacher Application Service besser ist: Camunda-, Temporal- und Orchestrator-Denken ohne Vendor-Lock-in.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Workflow Engines und Prozessautomation in Java als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Workflow Engines und Prozessautomation in Java sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class WorkflowDecision { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# workflow-engines-und-prozessautomation-in-java.yaml owner: enterprise-architecture chapter: 83 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 084 · Teil 5Search Architektur mit Elasticsearch und OpenSearchSuchsysteme als Read Model: Indexing, Consistency, Reindexing, Mapping, Analyzer, Datenschutz und Betriebsgrenzen.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Search Architektur mit Elasticsearch und OpenSearch als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Search Architektur mit Elasticsearch und OpenSearch sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class SearchIndexingPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# search-architektur-mit-elasticsearch-und-opensearch.yaml owner: enterprise-architecture chapter: 84 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 085 · Teil 5Cache Invalidation, Konsistenz und Performance Trade-offsCaching richtig einsetzen: TTL, Write-through, Cache-aside, Stampede-Schutz, Staleness und fachliche Konsequenzen.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Cache Invalidation, Konsistenz und Performance Trade-offs als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Cache Invalidation, Konsistenz und Performance Trade-offs sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CacheDecisionPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# cache-invalidation-konsistenz-und-performance-trade-offs.yaml owner: enterprise-architecture chapter: 85 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 086 · Teil 5Distributed Locks, Leader Election und Job-KoordinationWann verteilte Sperren nötig sind, warum sie gefährlich sein können und wie man Scheduler, Leader und Idempotenz kombiniert.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Distributed Locks, Leader Election und Job-Koordination als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Distributed Locks, Leader Election und Job-Koordination sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class LeaderElectionSketch { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# distributed-locks-leader-election-und-job-koordination.yaml owner: enterprise-architecture chapter: 86 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 087 · Teil 5API Lifecycle: Versioning, Deprecation und Consumer ManagementAPIs werden betrieben, nicht nur entwickelt: Versionen, Sunset, Consumer-Kommunikation, Breaking Changes und Compatibility Tests.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt API Lifecycle: Versioning, Deprecation und Consumer Management als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch API Lifecycle: Versioning, Deprecation und Consumer Management sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ApiLifecyclePolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# api-lifecycle-versioning-deprecation-und-consumer-management.yaml owner: enterprise-architecture chapter: 87 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 088 · Teil 5GraphQL im Enterprise-Java-KontextGraphQL als BFF-/Aggregationstechnik: Nutzen, Risiken, N+1-Probleme, Security, Caching und klare Grenzen zu Domain-APIs.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt GraphQL im Enterprise-Java-Kontext als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch GraphQL im Enterprise-Java-Kontext sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GraphQlBoundaryPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# graphql-im-enterprise-java-kontext.yaml owner: enterprise-architecture chapter: 88 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 089 · Teil 5gRPC und Protobuf für interne Java ServicesgRPC für interne Service-zu-Service-Kommunikation: Contracts, Streaming, Deadlines, Backward Compatibility und Observability.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt gRPC und Protobuf für interne Java Services als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch gRPC und Protobuf für interne Java Services sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GrpcContractPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# grpc-und-protobuf-fuer-interne-java-services.yaml owner: enterprise-architecture chapter: 89 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 090 · Teil 5Bulk APIs, Datenimporte und ReprocessingGroße Datenmengen sauber verarbeiten: Import-Jobs, Validierung, Staging, Quarantäne, Wiederanlauf und fachlicher Abgleich.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Bulk APIs, Datenimporte und Reprocessing als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Bulk APIs, Datenimporte und Reprocessing sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class BulkImportPipeline { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# bulk-apis-datenimporte-und-reprocessing.yaml owner: enterprise-architecture chapter: 90 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 091 · Teil 5Performance Engineering mit JMH, Gatling und k6Performance wird gemessen: Microbenchmarks, Lasttests, SLO-orientierte Szenarien, Kapazitätsgrenzen und Tuning-Schleifen.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Performance Engineering mit JMH, Gatling und k6 als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Performance Engineering mit JMH, Gatling und k6 sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class PerformanceExperiment { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# performance-engineering-mit-jmh-gatling-und-k6.yaml owner: enterprise-architecture chapter: 91 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 092 · Teil 5JVM GC Tuning: G1, ZGC und Shenandoah verstehenGarbage Collection für Enterprise Java: Latenz, Durchsatz, Heap, Pausen, Monitoring und sichere Tuning-Strategien.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt JVM GC Tuning: G1, ZGC und Shenandoah verstehen als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch JVM GC Tuning: G1, ZGC und Shenandoah verstehen sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GcTuningChecklist { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# jvm-gc-tuning-g1-zgc-und-shenandoah-verstehen.yaml owner: enterprise-architecture chapter: 92 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 093 · Teil 5Memory Leaks, Thread Dumps und Flame GraphsProduktionsdiagnose für Java: Heap Dumps, Thread Dumps, Lock Contention, CPU-Profile, Flame Graphs und Runbook-Entscheidungen.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Memory Leaks, Thread Dumps und Flame Graphs als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Memory Leaks, Thread Dumps und Flame Graphs sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class DiagnosticTriage { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# memory-leaks-thread-dumps-und-flame-graphs.yaml owner: enterprise-architecture chapter: 93 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 094 · Teil 5Datenbank-Performance: Indizes, Query Plans und LockingDatenbankperformance im Enterprise-Alltag: Indexstrategie, Query-Pläne, N+1, Locking, Partitionierung und ORM-Fallen.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Datenbank-Performance: Indizes, Query Plans und Locking als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Datenbank-Performance: Indizes, Query Plans und Locking sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class QueryPerformanceGuard { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# datenbank-performance-indizes-query-plans-und-locking.yaml owner: enterprise-architecture chapter: 94 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 095 · Teil 5Multi-Region, Disaster Recovery und Backup/RestoreBetrieb nach Ausfall denken: RPO, RTO, Replikation, Restore-Tests, DNS, Message Replay und Cutover-Pläne.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Multi-Region, Disaster Recovery und Backup/Restore als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Multi-Region, Disaster Recovery und Backup/Restore sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class DisasterRecoveryPlan { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# multi-region-disaster-recovery-und-backup-restore.yaml owner: enterprise-architecture chapter: 95 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 096 · Teil 5Blue/Green, Canary und Feature FlagsRelease-Strategien mit kontrolliertem Risiko: Blue/Green, Canary, Dark Launch, Feature Flags und schnelle Rollbacks.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Blue/Green, Canary und Feature Flags als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Blue/Green, Canary und Feature Flags sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ReleaseDecision { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# blue-green-canary-und-feature-flags.yaml owner: enterprise-architecture chapter: 96 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 097 · Teil 5Secrets, PKI und ZertifikatslebenszyklusSecrets und Zertifikate professionell betreiben: Rotation, Trust Stores, mTLS, Expiry-Alerts und Umgebungsgrenzen.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Secrets, PKI und Zertifikatslebenszyklus als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Secrets, PKI und Zertifikatslebenszyklus sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CertificateRotationPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# secrets-pki-und-zertifikatslebenszyklus.yaml owner: enterprise-architecture chapter: 97 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 098 · Teil 5Identity Architektur mit Keycloak und OIDCIdentity-Architektur für Enterprise Java: Realm, Clients, Scopes, Rollen, Token Relay, Service Accounts und Audit.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Identity Architektur mit Keycloak und OIDC als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Identity Architektur mit Keycloak und OIDC sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class IdentityAccessPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# identity-architektur-mit-keycloak-und-oidc.yaml owner: enterprise-architecture chapter: 98 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 099 · Teil 5OpenTelemetry Sampling, Traces, Metrics und Logs korrelierenObservability als Entscheidungshilfe: Sampling, Trace-Kontext, Metriken, Logs, Exemplars und Kostenkontrolle.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt OpenTelemetry Sampling, Traces, Metrics und Logs korrelieren als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch OpenTelemetry Sampling, Traces, Metrics und Logs korrelieren sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class TelemetryCorrelation { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# opentelemetry-sampling-traces-metrics-und-logs-korrelieren.yaml owner: enterprise-architecture chapter: 99 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 100 · Teil 5FinOps und Kapazitätsplanung für Java PlattformenKosten und Leistung zusammen betrachten: Requests/Limits, JVM-Memory, Autoscaling, Lizenzkosten, Umgebungen und Rightsizing.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt FinOps und Kapazitätsplanung für Java Plattformen als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch FinOps und Kapazitätsplanung für Java Plattformen sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CapacitySizingModel { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# finops-und-kapazitaetsplanung-fuer-java-plattformen.yaml owner: enterprise-architecture chapter: 100 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 101 · Teil 5Compliance, Audit Logging und Datenschutz-NachweiseTechnische Nachweise für regulierte Umgebungen: Audit Trails, Datenminimierung, Löschkonzepte, Zugriffsnachweise und Retention.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Compliance, Audit Logging und Datenschutz-Nachweise als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Compliance, Audit Logging und Datenschutz-Nachweise sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class AuditEvidenceModel { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# compliance-audit-logging-und-datenschutz-nachweise.yaml owner: enterprise-architecture chapter: 101 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 102 · Teil 5Open-Source-Lizenzen, GPL-Auswirkungen und Third-Party NoticesLizenzrisiken verstehen: permissive Lizenzen, Copyleft, GPL/AGPL-Folgen, Notices, SBOM und Review-Prozess.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Open-Source-Lizenzen, GPL-Auswirkungen und Third-Party Notices als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Open-Source-Lizenzen, GPL-Auswirkungen und Third-Party Notices sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class LicenseReviewRule { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# open-source-lizenzen-gpl-auswirkungen-und-third-party-notices.yaml owner: enterprise-architecture chapter: 102 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 103 · Teil 5Upgrade-Wellen mit Renovate, Dependabot und Release TrainsAbhängigkeiten kontrolliert aktualisieren: Gruppierung, Testgates, Rollback, Kompatibilität und Verantwortlichkeiten.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Upgrade-Wellen mit Renovate, Dependabot und Release Trains als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Upgrade-Wellen mit Renovate, Dependabot und Release Trains sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class UpgradeWavePolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# upgrade-wellen-mit-renovate-dependabot-und-release-trains.yaml owner: enterprise-architecture chapter: 103 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 104 · Teil 5Platform Engineering, IDP und Backstage-DenkenInterne Entwicklerplattformen: Golden Paths, Templates, Self-Service, Standards, Ownership und klare Produktverantwortung.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Platform Engineering, IDP und Backstage-Denken als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Platform Engineering, IDP und Backstage-Denken sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class GoldenPathTemplate { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# platform-engineering-idp-und-backstage-denken.yaml owner: enterprise-architecture chapter: 104 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 105 · Teil 5Contract-First APIs mit OpenAPI und AsyncAPIContracts zuerst denken: OpenAPI für REST, AsyncAPI für Events, Codegen, Contract Tests und Consumer-Kommunikation.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Contract-First APIs mit OpenAPI und AsyncAPI als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Contract-First APIs mit OpenAPI und AsyncAPI sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ContractFirstPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# contract-first-apis-mit-openapi-und-asyncapi.yaml owner: enterprise-architecture chapter: 105 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 106 · Teil 5Code Generation, Mapping und Boilerplate GovernanceCodegenerierung gezielt nutzen: MapStruct, OpenAPI-Generator, Annotation Processing, Generated Sources und Review-Regeln.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Code Generation, Mapping und Boilerplate Governance als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Code Generation, Mapping und Boilerplate Governance sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class CodeGenerationRule { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# code-generation-mapping-und-boilerplate-governance.yaml owner: enterprise-architecture chapter: 106 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 107 · Teil 5Maven Enforcer, Revapi und JApiCmpBuild-Governance im Maven-Projekt: Enforcer-Regeln, API-Break-Checks, Binary Compatibility und technische Schulden sichtbar machen.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Maven Enforcer, Revapi und JApiCmp als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Maven Enforcer, Revapi und JApiCmp sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class MavenQualityGate { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# maven-enforcer-revapi-und-japicmp.yaml owner: enterprise-architecture chapter: 107 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 108 · Teil 5ArchUnit Detailregeln für Enterprise JavaArchitektur als Test: Schichten, Zyklen, Modulgrenzen, Namensregeln, Dependency Rules und Ausnahmedokumentation.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt ArchUnit Detailregeln für Enterprise Java als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch ArchUnit Detailregeln für Enterprise Java sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class ArchUnitRuleSet { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# archunit-detailregeln-fuer-enterprise-java.yaml owner: enterprise-architecture chapter: 108 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 109 · Teil 5Effective Java Regeln für Enterprise ProjekteAusgewählte Effective-Java-Prinzipien im Enterprise-Kontext: Immutability, Builder, Exceptions, Generics, Concurrency und APIs.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Effective Java Regeln für Enterprise Projekte als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Effective Java Regeln für Enterprise Projekte sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class EffectiveJavaPolicy { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# effective-java-regeln-fuer-enterprise-projekte.yaml owner: enterprise-architecture chapter: 109 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Kapitel 110 · Teil 5Capstone: Migration Factory und Architektur-SimulationAbschlusskapitel: Wie man mehrere Legacy-Systeme systematisch bewertet, priorisiert, migriert und mit Architekturentscheidungen steuert.
Warum dieses Thema in Version 5 wichtig ist
Version 5 behandelt Capstone: Migration Factory und Architektur-Simulation als Senior-Thema. In echten Enterprise-Projekten reicht es nicht, eine Bibliothek einzubauen oder ein Pattern zu kennen. Entscheidend ist, ob die Lösung fachlich begründet, testbar, betreibbar, sicher und langfristig änderbar bleibt.
Orientierungsrahmen
| Aspekt | Erklärung |
|---|---|
| Ausgangspunkt | Das Thema wird als Teil einer produktionsreifen Java-Enterprise-Landschaft betrachtet, nicht als isolierte Technik. |
| Kernfrage | Welche fachliche Grenze, Betriebsgrenze oder Integrationsgrenze wird durch Capstone: Migration Factory und Architektur-Simulation sichtbar? |
| Risiko | Scheinbar technische Details erzeugen oft fachliche Nebenwirkungen: Datenverlust, Dopplungen, unklare Ownership, Sicherheitslücken oder hohe Betriebskosten. |
| Nachweis | ADR, Test, Runbook, Metrik, Trace, Contract, SBOM oder Code-Kommentar muss zeigen, dass die Entscheidung verstanden wurde. |
Technisches Beispiel
Das Beispiel zeigt absichtlich keine Framework-Magie. Die Regel wird als Java-Objekt formuliert. Dadurch kann sie in Spring Boot, Jakarta EE, Quarkus oder Micronaut verwendet und mit Unit-Tests abgesichert werden.
package at.aydinsude.enterprise.v5.sketch; import java.time.Instant; import java.util.List; import java.util.Map; // Pattern: Policy Object - kapselt eine wiederverwendbare Architekturregel. // Pattern: Strategy - unterschiedliche Projektsituationen können andere Bewertungen liefern. public final class MigrationFactorySimulation { public ArchitectureDecision evaluate(ArchitectureContext context) { int risk = context.businessCriticality() + context.integrationCount() + context.operationalComplexity(); String action = risk >= 9 ? "formal-review" : risk >= 5 ? "lightweight-adr" : "team-standard"; return new ArchitectureDecision(action, risk, Instant.now(), List.of( "document trade-offs", "add automated evidence", "define rollback or recovery path")); } public record ArchitectureContext(int businessCriticality, int integrationCount, int operationalComplexity, Map<String, String> tags) {} public record ArchitectureDecision(String action, int riskScore, Instant decidedAt, List<String> evidence) {} }
Die gleiche Entscheidung muss im Projekt sichtbar bleiben. Eine kleine YAML- oder Markdown-Dokumentation hilft, Standards zu automatisieren und Ausnahmen sauber zu erklären.
# capstone-migration-factory-und-architektur-simulation.yaml owner: enterprise-architecture chapter: 110 risk_level: senior evidence_required: - adr - architecture-test - runbook - monitoring-dashboard review: cadence: quarterly escalation: architecture-board
Typische Fehlerbilder
Prüffragen für Senior Entwickler
- Welche Entscheidung wird hier wirklich getroffen?
- Welche Alternative wurde bewusst verworfen?
- Welche Metrik zeigt im Betrieb, ob die Annahme noch stimmt?
- Welche Tests verhindern Rückfälle?
- Welche Dokumentation muss im Repository liegen?
- Welche Auswirkung hat das Thema auf Legacy-Migration, OpenShift-Betrieb und Kosten?
Merksatz
Praxislabor & Refactoring-Workshop
Labs, Refactoring-Workshops, Legacy-Modernisierung, Teststrategie und Capstone-Übungsstrecke.
Kapitel 111 · Teil 6V6 Praxislabor: Lernpfad vom Lesen zum UmsetzenV6 macht aus dem Lehrbuch ein Trainingssystem mit Labs, Lösungen, Prüfchecklisten und Capstone-Projekt.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class PraxislaborPlan { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 112 · Teil 6Lab 01: Maven Multi-Module sauber schneidenEin Lab für Parent-POM, Module, Dependency-Richtung, Enforcer-Regeln und Architekturgrenzen.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class MavenModuleGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 113 · Teil 6Lab 02: Domain Model, Aggregate und InvariantenBestellung, Positionen, Zahlung und Reservierung als fachliches Modell mit klaren Invarianten.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class AggregateInvariantGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 114 · Teil 6Lab 03: REST API mit Fehlervertrag und OpenAPIREST-Endpunkte, Problem Details, Validation, Versionierung und Consumer-Vertrag im Praxisbeispiel.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class RestContractGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 115 · Teil 6Lab 04: JPA, Transaktionen und Repository PatternJPA-Entities, Transaction Boundary, Repository-Port, Lazy Loading und N+1-Risiken verstehen.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class TransactionBoundaryGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 116 · Teil 6Lab 05: SOAP-Legacy-Adapter kapselnAlte SOAP-Clients werden hinter einem Port/Adapter isoliert, damit Domain und Use Cases sauber bleiben.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class SoapAdapterGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 117 · Teil 6Lab 06: Event-driven Outbox mit ReprocessingDomain Events, Outbox, Publisher, Retry, DLQ und fachliche Idempotenz als Übungsaufgabe.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class OutboxReprocessingGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 118 · Teil 6Lab 07: Security mit OAuth2/OIDC und RollenmodellJWT Claims, Rollen, Scopes, Token Relay und fachliche Berechtigungen im Enterprise-Kontext.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class AccessPolicyGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 119 · Teil 6Lab 08: Observability mit Logs, Metrics und TracesKorrelation, Trace-ID, Business-Metriken, SLO und Runbook-Verknüpfung praktisch einbauen.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class ObservabilityGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 120 · Teil 6Lab 09: Testing mit Unit, Contract und TestcontainersTestpyramide, Architekturtests, Contract Tests und Integrationstests mit Datenbank-/Broker-Simulation.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class TestingPyramidGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 121 · Teil 6Lab 10: OpenShift Deployment und ConfigContainer, ConfigMaps, Secrets, Health Checks, Ressourcenlimits, Routes und Rollout-Strategie.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class OpenShiftDeploymentGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 122 · Teil 6Lab 11: Performance, Diagnostik und LasttestsJMH, k6/Gatling-Denken, Thread Dumps, Heap Dumps und Query-Analyse als kontrollierte Diagnose.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class PerformanceDiagnosticGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 123 · Teil 6Lab 12: Final Capstone MigrationEin End-to-End-Lab: Legacy verstehen, modernisieren, absichern, testen, deployen und dokumentieren.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class CapstoneMigrationGuard { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 124 · Teil 6Refactoring Workshop: Monster Service zerlegenEin großer Vorher/Nachher-Workshop für Service-Monster, Transaktionsmischung, Mapping-Chaos und harte Infrastrukturkopplung.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class MonsterServiceRefactoring { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 125 · Teil 6Refactoring Workshop: JDBC-Spaghetti zu RepositoryLegacy-JDBC, SQL-Streuung und Ressourcenfehler werden Schritt für Schritt zu Ports und Repositories umgebaut.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class JdbcRepositoryRefactoring { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 126 · Teil 6Refactoring Workshop: EJB zu Application ServiceEJB-Session-Bean-Logik wird in Use Cases, Ports und klare Transaktionsgrenzen überführt.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class EjbToUseCaseRefactoring { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Entscheidungsbäume, Prüfung & Abschluss
Entscheidungsbäume, Interviewfragen, Produktionschecklisten und Abschluss-Lernpfad.
Kapitel 127 · Teil 7Refactoring Workshop: JSP/JSF zu REST und BFFUI-nahe Logik, Session State und HTML-Formularfluss werden in API, BFF und Frontend-Verträge getrennt.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class JspToBffRefactoring { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 128 · Teil 7Entscheidungsbaum: Spring Boot, Jakarta EE, Quarkus oder MicronautEin fachlicher Entscheidungsbaum für Team-Skills, Runtime, Cloud-Native, Standardisierung und Betriebsmodell.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class FrameworkDecisionTree { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 129 · Teil 7Entscheidungsbaum: REST, SOAP, Messaging, GraphQL oder gRPCIntegration wird bewusst gewählt: Consumer, Latenz, Kopplung, Vertrag, Streaming und Governance bestimmen die Wahl.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class IntegrationDecisionTree { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 130 · Teil 7Entscheidungsbaum: Monolith modularisieren oder Microservices schneidenTeamgrenzen, Datenhoheit, Releasefähigkeit und Betriebskosten entscheiden über den Schnitt.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class ServiceCutDecisionTree { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 131 · Teil 7Interviewtraining: Senior Java Enterprise FragenFragen und Musterantworten zu Architektur, Transaktionen, Messaging, Security, JPA, Maven und Betrieb.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class SeniorQuestionBank { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 132 · Teil 7Codeanalyse-Training: schlechte Beispiele erkennenCode-Smells, Transaktionsfehler, Exception-Probleme, N+1, fehlende Idempotenz und harte Kopplung erkennen.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class CodeReviewTraining { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 133 · Teil 7Prüfung: Multiple Choice und offene ArchitekturfragenEin prüfungsähnlicher Teil mit MC-Fragen, offenen Fragen, Lösungslogik und Bewertungsraster.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class ExamQuestionCatalog { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 134 · Teil 7Produktionsreife Checkliste: API und FehlerbehandlungEine kompakte Checkliste für APIs, Fehlerverträge, Validierung, Rate Limits, Security und Observability.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class ApiProductionChecklist { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 135 · Teil 7Produktionsreife Checkliste: DatenbankmigrationFlyway/Liquibase-Denken, Rollback, Backfill, Zero-Downtime, Locks, Indizes und Datenqualität.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class DbMigrationChecklist { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 136 · Teil 7Produktionsreife Checkliste: Security und ComplianceOIDC, Secrets, Audit, SBOM, Lizenzprüfung, Datenschutz und minimale Rechte als Produktionsstandard.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class SecurityComplianceChecklist { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 137 · Teil 7Produktionsreife Checkliste: Observability und IncidentSLO, Dashboards, Alerts, Runbooks, Incident-Timeline und Postmortem als Lernschleife.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class IncidentReadinessChecklist { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 138 · Teil 7Produktionsreife Checkliste: CI/CD und ReleaseBuild, Test, SBOM, Container Scan, Deployment Gates, Rollback und Freigabeprozess.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class ReleasePipelineChecklist { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 139 · Teil 7Capstone Architekturakte: ADRs, Runbooks und NachweiseDie finale Architekturakte bündelt Entscheidungen, Risiken, Verträge, Tests, Diagramme und Betriebsnachweise.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class ArchitectureEvidenceFile { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?
Kapitel 140 · Teil 7V6 Abschluss: Lernpfad, Wiederholung und nächste StufeAbschluss mit Wiederholungsplan, Selbsttest, Projektcheck und möglichen nächsten Vertiefungen.
Fachliches Ziel
Dieses V6-Kapitel ist bewusst als Umsetzungs- und Prüfkapitel gebaut. Du sollst nicht nur lesen, sondern eine Entscheidung, ein Codeartefakt, einen Testnachweis und eine kurze Betriebsdokumentation erzeugen.
Arbeitsauftrag
| Schritt | Teil | Erwartetes Ergebnis |
|---|---|---|
| 1 | Ausgangslage lesen | Altsystem, Stakeholder, Daten und Betriebsgrenzen sichtbar machen. |
| 2 | Schnitt festlegen | Domain, Application, Adapter und Deployment nicht vermischen. |
| 3 | Code umsetzen | Kleine Java-Klassen, klare Ports, keine Framework-Abhängigkeit im Kern. |
| 4 | Pattern markieren | Im Code kommentieren und in docs/design-patterns.md begründen. |
| 5 | Nachweis erstellen | Test, ADR, Runbook, Diagramm oder Checkliste hinzufügen. |
| 6 | Review durchführen | Risiken, Alternativen und nächste Verbesserung schriftlich festhalten. |
Vorher/Nachher-Denken
Viele Enterprise-Probleme entstehen nicht durch eine falsche Bibliothek, sondern durch vermischte Verantwortlichkeiten. Deshalb zeigt V6 häufiger eine schlechte Ausgangslage und eine klare Zielstruktur.
// Vorher: technische Logik, Fachlogik und Betriebsdetails sind vermischt. public void process(OrderDto dto) { // SQL, SOAP, Mapping, Transaktion, Event und Logging stehen in einer Methode. // Fehlerfolge: schwer testbar, schwer migrierbar, schwer betreibbar. }
// Nachher: klarer Use Case mit Ports und dokumentiertem Pattern. // Pattern: Hexagonal Architecture - Use Case kennt nur Ports, nicht Infrastruktur. public final class PlaceOrderUseCase { private final OrderRepository repository; private final PaymentPort paymentPort; private final DomainEventPort eventPort; public Receipt place(PlaceOrderCommand command) { Order order = Order.create(command.customerId(), command.lines()); paymentPort.authorize(order.total()); repository.save(order); eventPort.publish(order.orderPlaced()); return Receipt.from(order); } }
Java-Skizze für das Lab
Die folgende Klasse ist bewusst frameworkfrei. Sie kann lokal mit javac --release 21 kompiliert werden und zeigt die im Code markierten Entwurfsmuster.
package at.aydinsude.enterprise.v6.training; import java.time.Instant; import java.util.List; import java.util.UUID; // Pattern: Command - beschreibt eine auszuführende Lern-/Projektaktion als Objekt. // Pattern: Template Method - fixe Prüfschritte, aber variabler fachlicher Inhalt je Lab. // Pattern: Specification - Akzeptanzkriterien werden explizit prüfbar formuliert. public final class LearningPathReview { public TrainingResult execute(TrainingCommand command) { List<String> evidence = List.of( "code compiles", "design pattern documented", "architecture decision recorded", "test or checklist created", "runbook note added"); boolean accepted = command.description().length() > 20 && command.riskLevel() >= 1; return new TrainingResult(UUID.randomUUID(), accepted, evidence, Instant.now()); } public record TrainingCommand(String description, int riskLevel) {} public record TrainingResult(UUID id, boolean accepted, List<String> evidence, Instant checkedAt) {} }
Typische Fehler und Gegenmaßnahmen
Gegenmaßnahme: Eine kurze ADR mit Kontext, Entscheidung, Alternativen und Konsequenzen ergänzen.
Gegenmaßnahme: Pattern-Kommentar direkt an der Klasse oder Methode und zusätzlich in
docs/design-patterns.md.Gegenmaßnahme: Runbook, Metrik, Log-Korrelation oder Checkliste als Nachweis anlegen.
Prüffragen
- Welche fachliche Grenze wird hier geschützt?
- Welche technische Abhängigkeit wird absichtlich isoliert?
- Welches Entwurfsmuster ist im Code sichtbar?
- Welche Tests würden einen Rückfall verhindern?
- Welche Metrik oder welches Log hilft im Betrieb?