30 Architekturmodule

Enterprise Architecture Explorer

Alle zugehörigen Inhalte befinden sich auf dieser einen großen Seite. Kapitel und Beispiele sind standardmäßig geschlossen und lassen sich gezielt öffnen.

Fachlicher Lernpfad

Grundlage → Entscheidungskriterien → Refactoring-Pfad → ausführbare Referenz → Einsatzgrenzen

Lernzielorientierter Zugang

Architektur nach Entscheidungsfragen lernen

Die vorhandenen Kapitel bleiben vollständig erhalten. Diese Orientierung gruppiert sie nach den Entscheidungen, die ein Enterprise-Team tatsächlich treffen muss.

Systemgrenzen

Layered, Hexagonal und Clean Architecture danach vergleichen, wie Abhängigkeiten kontrolliert werden.

Modularisierung

Modularen Monolithen als prüfbaren Zwischenschritt vor verteilten Systemen verstehen.

Migration

Für jede Zielarchitektur einen inkrementellen Migrationspfad statt eines Big Bang ableiten.

Betrieb

Transaktionen, Beobachtbarkeit, Datenbesitz und Ausfallgrenzen als Architekturkräfte behandeln.

Kapitel 1 Schichtenarchitektur und gerichtete Abhängigkeiten6 Architekturmodelle

Sechs Architekturmodule zeigen nicht nur Diagramme, sondern Kräfte, Grenzen, Java-Zuordnung, Migrationspfad und Alternativen.

Architekturabschnitt 1

Enterprise Architecture Explorer

Sechs Architekturmodule zeigen nicht nur Diagramme, sondern Kräfte, Grenzen, Java-Zuordnung, Migrationspfad und Alternativen.

Fachlicher Lernpfad

Grundlage → Entscheidungskriterien → Refactoring-Pfad → ausführbare Referenz → Einsatzgrenzen

Modul 1 Layered Architecture Abhängigkeiten fließen durch klar getrennte Präsentations-, Anwendungs-, Domänen- und Infrastrukturschichten.

Layered Architecture Architekturdiagramm

Geeignet

Kleine bis mittlere Systeme mit stabilen Schichtgrenzen

Leitplanke

Domänenlogik darf nicht in Controller oder Persistenzschicht wandern

Alternative

Hexagonal Architecture

Nicht wählen

Wenn Adapter austauschbar sein müssen oder Tests durch Infrastrukturkopplung leiden

Abhängigkeitsfluss

Controller -> Application -> Domain -> Infrastructure

Migrationspfad

Grenze zuerst sichtbar machen, Vertrag stabilisieren, Abhängigkeiten umdrehen und erst danach Infrastruktur verschieben.

LayeredArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Layered Architecture
// Zweck: Verantwortlichkeiten nach technischen und fachlichen Schichten ordnen.
public final class LayeredArchitectureModule {
  public record PlaceOrderCommand(String customerId,long totalMinor) {}
  public interface OrderRepository { void save(Order order); }
  public record Order(String customerId,long totalMinor) {}
  public static final class PlaceOrderUseCase {
    private final OrderRepository repository;
    public PlaceOrderUseCase(OrderRepository repository){ this.repository=repository; }
    public Order execute(PlaceOrderCommand command){
      if(command.totalMinor()<=0) throw new IllegalArgumentException("totalMinor");
      var order=new Order(command.customerId(),command.totalMinor());
      repository.save(order); return order;
    }
  }
}

Modul 2 Hexagonal Architecture Der fachliche Kern kommuniziert ausschließlich über Ports; Adapter kapseln REST, Datenbank und Messaging.

Hexagonal Architecture Architekturdiagramm

Geeignet

Systeme mit mehreren Ein- und Ausgängen und hohem Testbedarf

Leitplanke

Ports fachlich benennen; keine Framework-Typen im Kern

Alternative

Clean Architecture

Nicht wählen

Wenn ein einfaches Schichtenmodell ausreicht

Abhängigkeitsfluss

Adapter -> Port -> Use Case -> Port -> Adapter

Migrationspfad

Grenze zuerst sichtbar machen, Vertrag stabilisieren, Abhängigkeiten umdrehen und erst danach Infrastruktur verschieben.

HexagonalArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Hexagonal Architecture (Ports and Adapters)
// Zweck: Fachlogik unabhängig von technischen Ein- und Ausgängen halten.
public final class HexagonalArchitectureModule {
  public record Money(long minor,String currency) {}
  public interface LoadCustomerPort { Customer load(String id); }
  public interface PublishDecisionPort { void publish(Decision decision); }
  public record Customer(String id,boolean active) {}
  public record Decision(String customerId,boolean approved) {}
  public static final class ApproveCustomerUseCase {
    private final LoadCustomerPort customers; private final PublishDecisionPort events;
    public ApproveCustomerUseCase(LoadCustomerPort c,PublishDecisionPort e){customers=c;events=e;}
    public Decision execute(String id){ var c=customers.load(id); var d=new Decision(id,c.active()); events.publish(d); return d; }
  }
}

Modul 3 Clean Architecture Use Cases bilden den Anwendungsring; äußere Frameworks hängen nach innen, nie umgekehrt.

Clean Architecture Architekturdiagramm

Geeignet

Langfristige Produkte mit mehreren Delivery-Mechanismen

Leitplanke

Ringgrenzen nicht mit unnötigen DTO-Kopien überfrachten

Alternative

Hexagonal Architecture

Nicht wählen

Wenn zusätzliche Ringe keinen echten Änderungsdruck adressieren

Abhängigkeitsfluss

Frameworks -> Interface Adapters -> Use Cases -> Entities

Migrationspfad

Grenze zuerst sichtbar machen, Vertrag stabilisieren, Abhängigkeiten umdrehen und erst danach Infrastruktur verschieben.

CleanArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Clean Architecture
// Zweck: Use Cases und Enterprise-Regeln vor Framework- und UI-Details schützen.
public final class CleanArchitectureModule {
  public record RegisterRequest(String email) {}
  public record RegisterResponse(String customerId) {}
  public interface CustomerGateway { String insert(String normalizedEmail); }
  public interface RegisterInputBoundary { RegisterResponse register(RegisterRequest request); }
  public static final class RegisterInteractor implements RegisterInputBoundary {
    private final CustomerGateway gateway;
    public RegisterInteractor(CustomerGateway gateway){this.gateway=gateway;}
    public RegisterResponse register(RegisterRequest r){
      var email=r.email().trim().toLowerCase();
      if(!email.contains("@")) throw new IllegalArgumentException("email");
      return new RegisterResponse(gateway.insert(email));
    }
  }
}

Modul 4 Modular Monolith Ein Deployment enthält fachlich abgeschlossene Module mit expliziten öffentlichen APIs.

Modular Monolith Architekturdiagramm

Geeignet

Wachsende Domänen, die unabhängig strukturiert, aber gemeinsam betrieben werden

Leitplanke

Keine direkten Tabellen- oder Package-Zugriffe zwischen Modulen

Alternative

Microservices

Nicht wählen

Wenn unabhängige Skalierung und Deployment zwingend erforderlich sind

Abhängigkeitsfluss

Module API -> Module intern; gemeinsame Laufzeit

Migrationspfad

Grenze zuerst sichtbar machen, Vertrag stabilisieren, Abhängigkeiten umdrehen und erst danach Infrastruktur verschieben.

ModularMonolithModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Modular Monolith
// Zweck: Fachmodule stark kapseln, ohne verteilte Betriebs- und Konsistenzkosten.
public final class ModularMonolithModule {
  public interface BillingApi { Invoice issueFor(String orderId,long totalMinor); }
  public record Invoice(String id,String orderId,long totalMinor) {}
  public static final class OrderModule {
    private final BillingApi billing;
    public OrderModule(BillingApi billing){this.billing=billing;}
    public Invoice complete(String orderId,long totalMinor){ return billing.issueFor(orderId,totalMinor); }
  }
  private ModularMonolithModule() {}
}

Modul 5 Microservices Architecture Autonome Services besitzen Daten und Deployment und kommunizieren über explizite Verträge.

Microservices Architecture Architekturdiagramm

Geeignet

Unabhängige Teams, unterschiedliche Skalierung und klare Bounded Contexts

Leitplanke

Verteilte Transaktionen, Observability und Vertragsversionierung bewusst tragen

Alternative

Modular Monolith

Nicht wählen

Wenn Team- und Deployment-Autonomie den Betriebsaufwand nicht rechtfertigen

Abhängigkeitsfluss

Service Contract -> Network -> Autonomous Service

Migrationspfad

Grenze zuerst sichtbar machen, Vertrag stabilisieren, Abhängigkeiten umdrehen und erst danach Infrastruktur verschieben.

MicroservicesArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.UUID;
// Architecture Pattern: Microservices
// Zweck: Fachliche Fähigkeiten unabhängig deployen und skalieren.
public final class MicroservicesArchitectureModule {
  public record ReserveInventoryRequest(String correlationId,String sku,int quantity) {
    public static ReserveInventoryRequest of(String sku,int qty){return new ReserveInventoryRequest(UUID.randomUUID().toString(),sku,qty);}
  }
  public record ReservationReply(String correlationId,boolean reserved) {}
  public interface InventoryClient { ReservationReply reserve(ReserveInventoryRequest request); }
  public static final class CheckoutService {
    private final InventoryClient inventory;
    public CheckoutService(InventoryClient inventory){this.inventory=inventory;}
    public ReservationReply checkout(String sku,int quantity){return inventory.reserve(ReserveInventoryRequest.of(sku,quantity));}
  }
}

Modul 6 Event-Driven Architecture Produzenten veröffentlichen Ereignisse; unabhängige Konsumenten reagieren asynchron.

Event-Driven Architecture Architekturdiagramm

Geeignet

Mehrere unabhängige Reaktionen, Integrationsentkopplung und hohe Änderungsrate

Leitplanke

Idempotenz, Reihenfolge, Schemaevolution und Fehlerkanäle explizit lösen

Alternative

Request-Response

Nicht wählen

Wenn eine sofortige konsistente Antwort benötigt wird

Abhängigkeitsfluss

Producer -> Event Bus -> Independent Consumers

Migrationspfad

Grenze zuerst sichtbar machen, Vertrag stabilisieren, Abhängigkeiten umdrehen und erst danach Infrastruktur verschieben.

EventDrivenArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.time.Instant;
// Architecture Pattern: Event-Driven Architecture
// Zweck: Fachliche Reaktionen zeitlich und organisatorisch entkoppeln.
public final class EventDrivenArchitectureModule {
  public record OrderCompleted(String eventId,String orderId,long totalMinor,Instant occurredAt) {}
  public interface EventPublisher { void publish(OrderCompleted event); }
  public static final class CompleteOrderUseCase {
    private final EventPublisher publisher;
    public CompleteOrderUseCase(EventPublisher publisher){this.publisher=publisher;}
    public void execute(String eventId,String orderId,long totalMinor){
      if(totalMinor<=0) throw new IllegalArgumentException("totalMinor");
      publisher.publish(new OrderCompleted(eventId,orderId,totalMinor,Instant.now()));
    }
  }
}
Kapitel 2 CQRS, Event-getriebene Systeme und Lesemodelle6 Architekturmodelle

Sechs weitere Architekturentscheidungen für verteilte Daten, Prozesse, Plattformgrenzen und Fehlerisolation.

Architekturabschnitt 2

Enterprise Architecture Explorer

Sechs weitere Architekturentscheidungen für verteilte Daten, Prozesse, Plattformgrenzen und Fehlerisolation.

Fachlicher Lernpfad

Grundlage → Entscheidungskriterien → Refactoring-Pfad → ausführbare Referenz → Einsatzgrenzen

Modul 7 CQRS Architecture Command and Query Responsibility Segregation trennt Schreibmodelle von spezialisierten Lesemodellen.

CQRS Architecture Architekturdiagramm

Geeignet

Hohe Lese-/Schreibasymmetrie und unterschiedliche Modellanforderungen

Leitplanke

Konsistenz, Projektionen und Betriebsaufwand explizit behandeln

Alternative

CRUD oder modulare Schichten

Abhängigkeitsfluss

Command -> Write Model -> Event -> Projection -> Query Model

Migrationspfad

Grenze und Messgrößen zuerst definieren, eine vertikale Scheibe migrieren, Verhalten absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Idempotenz und Architekturgrenzen automatisiert prüfen.

CqrsArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.Map; import java.util.concurrent.ConcurrentHashMap;
// Architecture Pattern: CQRS
// Zweck: Schreibentscheidungen und optimierte Leseprojektionen bewusst trennen.
public final class CqrsArchitectureModule {
  public record ChangePrice(String sku,long minor) {} public record ProductView(String sku,long minor) {}
  public interface CommandHandler { void handle(ChangePrice command); }
  public interface ProductQuery { ProductView bySku(String sku); }
  public static final class ProductProjection implements ProductQuery {
    private final Map<String,ProductView> views=new ConcurrentHashMap<>();
    public void project(ChangePrice c){views.put(c.sku(),new ProductView(c.sku(),c.minor()));}
    public ProductView bySku(String sku){return views.get(sku);}
  }
}

Modul 8 Event Sourcing Architecture Der aktuelle Zustand entsteht durch das Wiederabspielen unveränderlicher Fachereignisse.

Event Sourcing Architecture Architekturdiagramm

Geeignet

Auditierbare Domänen mit zeitlicher Nachvollziehbarkeit und seltenen Modellwechseln

Leitplanke

Ereignisschema, Snapshots und Wiederaufbau dauerhaft beherrschen

Alternative

State-based Persistence

Abhängigkeitsfluss

Command -> Aggregate -> Events -> Event Store -> Replay

Migrationspfad

Grenze und Messgrößen zuerst definieren, eine vertikale Scheibe migrieren, Verhalten absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Idempotenz und Architekturgrenzen automatisiert prüfen.

EventSourcingArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.List;
// Architecture Pattern: Event Sourcing
// Zweck: Zustand als Ergebnis einer unveränderlichen Ereignisfolge rekonstruieren.
public final class EventSourcingArchitectureModule {
  public sealed interface AccountEvent permits Opened,Deposited {}
  public record Opened(String accountId) implements AccountEvent {} public record Deposited(long minor) implements AccountEvent {}
  public record AccountState(String id,long balance) {
    public static AccountState replay(List<AccountEvent> events){ AccountState s=new AccountState("",0); for(var e:events){ if(e instanceof Opened o)s=new AccountState(o.accountId(),0); else if(e instanceof Deposited d)s=new AccountState(s.id(),s.balance()+d.minor()); } return s;}
  }
}

Modul 9 Saga Architecture Mehrere lokale Transaktionen werden durch Schritte und kompensierende Aktionen zu einem verteilten Geschäftsprozess verbunden.

Saga Architecture Architekturdiagramm

Geeignet

Lange Geschäftsprozesse über autonome Services ohne globale Transaktion

Leitplanke

Kompensation ist Fachlogik; Wiederholung und Beobachtbarkeit sind Pflicht

Alternative

Process Manager oder atomare lokale Transaktion

Abhängigkeitsfluss

Start -> Reserve -> Charge -> Ship / Compensate

Migrationspfad

Grenze und Messgrößen zuerst definieren, eine vertikale Scheibe migrieren, Verhalten absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Idempotenz und Architekturgrenzen automatisiert prüfen.

SagaArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Saga
// Zweck: Verteilte Geschäftsprozesse über lokale Transaktionen und Kompensationen koordinieren.
public final class SagaArchitectureModule {
  public interface Inventory { void reserve(String orderId); void release(String orderId); }
  public interface Payment { void charge(String orderId); }
  public static final class CheckoutSaga {
    private final Inventory inventory; private final Payment payment;
    public CheckoutSaga(Inventory i,Payment p){inventory=i;payment=p;}
    public void execute(String orderId){ inventory.reserve(orderId); try{payment.charge(orderId);}catch(RuntimeException ex){inventory.release(orderId);throw ex;} }
  }
}

Modul 10 API Gateway Architecture Ein zentraler Eintrittspunkt bündelt Routing, Authentisierung, Quoten und externe API-Verträge.

API Gateway Architecture Architekturdiagramm

Geeignet

Viele externe Clients und mehrere interne Services mit einheitlichen Edge-Regeln

Leitplanke

Keine Fachlogik oder verteilte Monolith-Kopplung im Gateway

Alternative

Backend for Frontend oder direkte Service-APIs

Abhängigkeitsfluss

Client -> Gateway -> Service Routes

Migrationspfad

Grenze und Messgrößen zuerst definieren, eine vertikale Scheibe migrieren, Verhalten absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Idempotenz und Architekturgrenzen automatisiert prüfen.

ApiGatewayArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.Map;
// Architecture Pattern: API Gateway
// Zweck: Externe Zugriffe über einen stabilen Edge-Vertrag zu internen Services routen.
public final class ApiGatewayArchitectureModule {
  public interface Route { String invoke(String payload); }
  public static final class Gateway {
    private final Map<String,Route> routes; public Gateway(Map<String,Route> routes){this.routes=Map.copyOf(routes);}
    public String dispatch(String path,String payload){var route=routes.get(path); if(route==null)throw new IllegalArgumentException("route"); return route.invoke(payload);}
  }
}

Modul 11 Service Mesh Architecture Kommunikationsfunktionen wie mTLS, Retry, Telemetrie und Routing liegen in einer Infrastruktur-Schicht neben den Services.

Service Mesh Architecture Architekturdiagramm

Geeignet

Viele Services mit einheitlichen Transportregeln und Plattformbetrieb

Leitplanke

Fachliche Wiederholungslogik und Domänenentscheidungen bleiben im Service

Alternative

Library-based Service Communication

Abhängigkeitsfluss

Service -> Sidecar/Data Plane -> Service; Control Plane steuert

Migrationspfad

Grenze und Messgrößen zuerst definieren, eine vertikale Scheibe migrieren, Verhalten absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Idempotenz und Architekturgrenzen automatisiert prüfen.

ServiceMeshArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Service Mesh
// Zweck: Einheitliche Transport- und Observability-Regeln außerhalb der Fachlogik betreiben.
public final class ServiceMeshArchitectureModule {
  public record Request(String service,String body) {} public record Response(int status,String body) {}
  public interface DataPlane { Response forward(Request request); }
  public static final class OrderClient {
    private final DataPlane mesh; public OrderClient(DataPlane mesh){this.mesh=mesh;}
    public Response load(String id){return mesh.forward(new Request("order-service","/orders/"+id));}
  }
}

Modul 12 Cell-Based Architecture Das System wird in weitgehend autonome, wiederholbare Zellen partitioniert, um Fehlerausbreitung und Blast Radius zu begrenzen.

Cell-Based Architecture Architekturdiagramm

Geeignet

Große Multi-Tenant-Plattformen mit klarer Partitionierung und hoher Verfügbarkeit

Leitplanke

Zellrouting, Datenplatzierung und Cross-Cell-Prozesse explizit entwerfen

Alternative

Shared Cluster oder klassische Microservices

Abhängigkeitsfluss

Router -> Cell A/B/C -> isolated data and services

Migrationspfad

Grenze und Messgrößen zuerst definieren, eine vertikale Scheibe migrieren, Verhalten absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Idempotenz und Architekturgrenzen automatisiert prüfen.

CellBasedArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.List;
// Architecture Pattern: Cell-Based Architecture
// Zweck: Mandanten und Last auf isolierte, wiederholbare Zellen verteilen.
public final class CellBasedArchitectureModule {
  public record Cell(String id,String endpoint) {}
  public static final class CellRouter {
    private final List<Cell> cells; public CellRouter(List<Cell> cells){if(cells.isEmpty())throw new IllegalArgumentException("cells");this.cells=List.copyOf(cells);}
    public Cell route(String tenantId){return cells.get(Math.floorMod(tenantId.hashCode(),cells.size()));}
  }
}
Kapitel 3 Mandantenfähigkeit, Isolation und Plattformgrenzen6 Architekturmodelle

Sechs Architekturentscheidungen für Mandantenfähigkeit, elastische Ausführung, hochskalierende Datenräume und dezentrale Verarbeitung.

Architekturabschnitt 3

Enterprise Architecture Explorer

Sechs Architekturentscheidungen für Mandantenfähigkeit, elastische Ausführung, hochskalierende Datenräume und dezentrale Verarbeitung.

Fachlicher Lernpfad

Grundlage → Entscheidungskriterien → Refactoring-Pfad → ausführbare Referenz → Einsatzgrenzen

Modul 13 Multi-Tenant Architecture Mehrere Mandanten teilen eine Plattform, während Identität, Daten und Betrieb sauber isoliert bleiben.

Multi-Tenant Architecture

Geeignet

SaaS-Plattformen mit gemeinsamer Produktlogik und klarer Tenant-Grenze

Leitplanke

Tenant-Kontext muss durch jede Schicht propagiert und serverseitig geprüft werden

Alternative

Separate Deployments pro Kunde

Abhängigkeitsfluss

Request -> Tenant Context -> Use Case -> Tenant-aware Repository

Migrationspfad

Zuerst Grenze und Messgrößen definieren, eine vertikale Scheibe absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Isolation, Konsistenz und Wiederanlauf automatisiert prüfen.

MultiTenantArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Multi-Tenant Architecture
// Zweck: Mandantenkontext explizit durch Use Case und Persistenzgrenze führen.
public final class MultiTenantArchitectureModule {
  public record TenantId(String value){ public TenantId{ if(value==null||value.isBlank()) throw new IllegalArgumentException("tenant"); }}
  public record Order(TenantId tenantId,String orderId){}
  public interface OrderRepository { Order find(TenantId tenantId,String orderId); }
  public static final class LoadOrder {
    private final OrderRepository repository; public LoadOrder(OrderRepository r){this.repository=r;}
    public Order execute(TenantId tenantId,String orderId){return repository.find(tenantId,orderId);}
  }
}

Modul 14 Serverless Architecture Kurzlebige Funktionen reagieren auf Ereignisse oder Requests und skalieren unabhängig.

Serverless Architecture

Geeignet

Ereignisgetriebene, unregelmäßige Last mit klar begrenzten Funktionen

Leitplanke

Cold Starts, Laufzeitlimits, Zustandslosigkeit und Provider-Kopplung bewusst behandeln

Alternative

Container-basierte Services

Abhängigkeitsfluss

Event -> Function -> Port -> External Service

Migrationspfad

Zuerst Grenze und Messgrößen definieren, eine vertikale Scheibe absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Isolation, Konsistenz und Wiederanlauf automatisiert prüfen.

ServerlessArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Serverless Architecture
// Zweck: Eine kleine zustandslose Funktion über Ports an Infrastruktur anbinden.
public final class ServerlessArchitectureModule {
  public record InvoiceRequested(String invoiceId){}
  public interface InvoicePort { void generate(String invoiceId); }
  public static final class InvoiceFunction {
    private final InvoicePort port; public InvoiceFunction(InvoicePort p){this.port=p;}
    public void handle(InvoiceRequested event){port.generate(event.invoiceId());}
  }
}

Modul 15 Space-Based Architecture Zustand und Verarbeitung werden über verteilte In-Memory-Spaces partitioniert, um Datenbankengpässe zu vermeiden.

Space-Based Architecture

Geeignet

Extrem hohe Last, temporäre Zustände und horizontale Partitionierung

Leitplanke

Konsistenzmodell, Rebalancing und Persistenzrückfluss explizit entwerfen

Alternative

Event-Driven Microservices mit externer Datenbank

Abhängigkeitsfluss

Router -> Partitioned Space -> Processing Unit -> Durable Store

Migrationspfad

Zuerst Grenze und Messgrößen definieren, eine vertikale Scheibe absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Isolation, Konsistenz und Wiederanlauf automatisiert prüfen.

SpaceBasedArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.concurrent.ConcurrentHashMap;
// Architecture Pattern: Space-Based Architecture
// Zweck: Arbeitszustand partitioniert im Speicher halten und lokal verarbeiten.
public final class SpaceBasedArchitectureModule {
  public record Cart(String id,long totalMinor){}
  public static final class CartSpace {
    private final ConcurrentHashMap<String,Cart> carts=new ConcurrentHashMap<>();
    public Cart update(String id,long delta){return carts.compute(id,(k,v)->new Cart(id,(v==null?0:v.totalMinor())+delta));}
  }
}

Modul 16 Pipe-and-Filter Architecture Eine Verarbeitung wird in unabhängige, kombinierbare Filter mit klaren Ein- und Ausgaben zerlegt.

Pipe-and-Filter Architecture

Geeignet

Import, Transformation, Validierung und Datenaufbereitung

Leitplanke

Filter müssen klein, beobachtbar und möglichst seiteneffektfrei bleiben

Alternative

Template Method oder monolithischer Batch

Abhängigkeitsfluss

Input -> Parse -> Validate -> Enrich -> Persist

Migrationspfad

Zuerst Grenze und Messgrößen definieren, eine vertikale Scheibe absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Isolation, Konsistenz und Wiederanlauf automatisiert prüfen.

PipeAndFilterArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.List;
// Architecture Pattern: Pipe and Filter
// Zweck: Verarbeitungsschritte als unabhängige Filter komponieren.
public final class PipeAndFilterArchitectureModule {
  public interface Filter { String apply(String input); }
  public static final class Pipeline {
    private final List<Filter> filters; public Pipeline(List<Filter> f){filters=List.copyOf(f);}
    public String run(String input){String value=input; for(Filter f:filters)value=f.apply(value); return value;}
  }
}

Modul 17 Blackboard Architecture Spezialisierte Komponenten arbeiten über einen gemeinsamen Wissensspeicher iterativ an einer Lösung.

Blackboard Architecture

Geeignet

Komplexe Analyseprobleme mit mehreren unabhängigen Heuristiken

Leitplanke

Gemeinsamer Zustand braucht Versionierung, Priorisierung und klare Abbruchkriterien

Alternative

Pipeline oder Orchestrator

Abhängigkeitsfluss

Knowledge Sources <-> Blackboard -> Controller

Migrationspfad

Zuerst Grenze und Messgrößen definieren, eine vertikale Scheibe absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Isolation, Konsistenz und Wiederanlauf automatisiert prüfen.

BlackboardArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.*;
// Architecture Pattern: Blackboard
// Zweck: Mehrere Analysekomponenten über einen gemeinsamen Wissensspeicher koordinieren.
public final class BlackboardArchitectureModule {
  public static final class Blackboard { private final Map<String,Object> facts=new HashMap<>(); public void put(String k,Object v){facts.put(k,v);} public Object get(String k){return facts.get(k);} }
  public interface KnowledgeSource { boolean supports(Blackboard board); void contribute(Blackboard board); }
  public static void solve(Blackboard board,List<KnowledgeSource> sources){for(var s:sources)if(s.supports(board))s.contribute(board);}
}

Modul 18 Peer-to-Peer Architecture Gleichberechtigte Knoten teilen Verantwortung und kommunizieren ohne zentrale Instanz.

Peer-to-Peer Architecture

Geeignet

Dezentrale Replikation, lokale Autonomie und robuste Verteilung

Leitplanke

Konfliktauflösung, Discovery, Authentisierung und Konsens sind Kernprobleme

Alternative

Leader-basierte Clusterarchitektur

Abhängigkeitsfluss

Peer A <-> Peer B <-> Peer C

Migrationspfad

Zuerst Grenze und Messgrößen definieren, eine vertikale Scheibe absichern und erst danach skalieren.

Testfokus

Verträge, Fehlerpfade, Isolation, Konsistenz und Wiederanlauf automatisiert prüfen.

PeerToPeerArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.Set;
// Architecture Pattern: Peer-to-Peer
// Zweck: Gleichberechtigte Knoten über ein kleines Replikationsprotokoll verbinden.
public final class PeerToPeerArchitectureModule {
  public record Change(String id,long version,String value){}
  public interface Peer { void receive(Change change); }
  public static final class Replicator {
    private final Set<Peer> peers; public Replicator(Set<Peer> peers){this.peers=Set.copyOf(peers);}
    public void publish(Change change){peers.forEach(p->p.receive(change));}
  }
}
Kapitel 4 Hexagonal, Onion und Ports-and-Adapters6 Architekturmodelle

Sechs Architekturentscheidungen für Domänenzentrierung, erweiterbare Plattformen und moderne Datenverarbeitung.

Architekturabschnitt 4

Enterprise Architecture Explorer

Sechs Architekturentscheidungen für Domänenzentrierung, erweiterbare Plattformen und moderne Datenverarbeitung.

Fachlicher Lernpfad

Grundlage → Entscheidungskriterien → Refactoring-Pfad → ausführbare Referenz → Einsatzgrenzen

Modul 19 Onion Architecture Domänenmodell und fachliche Regeln liegen im Zentrum; technische Abhängigkeiten zeigen konsequent nach innen.

Onion Architecture

Geeignet

Komplexe Fachdomänen mit langlebigen Geschäftsregeln

Leitplanke

Abhängigkeitsregel und Modellreinheit müssen in Build und Reviews geschützt werden

Alternative

Hexagonal Architecture

Abhängigkeitsfluss

UI/Adapter -> Application -> Domain

Migrationspfad

Fachlogik aus Services ins Domänenmodell ziehen, Ports definieren, Infrastruktur nach außen verschieben

Testfokus

Domainregeln ohne Framework testen; Adapter separat per Vertrag prüfen

OnionArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Onion Architecture
// Zweck: Fachlogik im inneren Ring halten und Infrastruktur nur über Ports anbinden.
public final class OnionArchitectureModule {
  public record Money(long minor) { public Money add(Money other){ return new Money(minor + other.minor); } }
  public interface OrderPort { void save(Order order); }
  public static final class Order {
    private Money total = new Money(0);
    public void add(Money price){ if(price.minor() < 0) throw new IllegalArgumentException("price"); total = total.add(price); }
    public Money total(){ return total; }
  }
  public static final class PlaceOrder {
    private final OrderPort port; public PlaceOrder(OrderPort port){ this.port=port; }
    public void execute(Order order){ port.save(order); }
  }
}

Modul 20 Microkernel Architecture Ein stabiler Kern stellt minimale Fähigkeiten bereit; Plugins erweitern Fachfunktionen ohne den Kern zu verändern.

Microkernel Architecture

Geeignet

Produkte mit kundenspezifischen Erweiterungen und austauschbaren Modulen

Leitplanke

Plugin-Verträge, Versionierung und Isolation müssen explizit sein

Alternative

Modular Monolith

Abhängigkeitsfluss

Host -> Kernel API -> Plugin

Migrationspfad

Erweiterungspunkte identifizieren, Vertrag extrahieren, vorhandene Varianten als Plugins migrieren

Testfokus

Kompatibilitätstests pro Plugin und Kernvertrag

MicrokernelArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.*;
// Architecture Pattern: Microkernel
// Zweck: Stabilen Kern durch versionierte Plugins erweitern.
public final class MicrokernelArchitectureModule {
  public interface PricingPlugin { String id(); long price(long baseMinor); }
  public static final class Kernel {
    private final Map<String,PricingPlugin> plugins;
    public Kernel(Collection<PricingPlugin> plugins){ this.plugins=new HashMap<>(); plugins.forEach(p->this.plugins.put(p.id(),p)); }
    public long price(String pluginId,long baseMinor){ var p=plugins.get(pluginId); if(p==null) throw new IllegalArgumentException("plugin"); return p.price(baseMinor); }
  }
}

Modul 21 Data Mesh Architecture Domänenteams verantworten Datenprodukte mit klaren Verträgen, Qualitätszielen und föderierten Plattformstandards.

Data Mesh Architecture

Geeignet

Viele Fachdomänen mit zentralem Datenengpass

Leitplanke

Ownership ohne interoperable Verträge erzeugt neue Silos

Alternative

Zentrales Data Warehouse

Abhängigkeitsfluss

Domain Source -> Data Product -> Federated Catalog

Migrationspfad

Ein priorisiertes Datenprodukt mit Owner, Schema, SLO und Zugriffspolitik etablieren

Testfokus

Schema-, Qualitäts-, Zugriffs- und Freshness-Verträge automatisieren

DataMeshArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.time.*;
// Architecture Pattern: Data Mesh
// Zweck: Ein fachlich verantwortetes Datenprodukt mit explizitem Vertrag modellieren.
public final class DataMeshArchitectureModule {
  public record OrderFact(String orderId,long totalMinor,Instant occurredAt){}
  public interface OrderDataProduct { OrderFact byId(String orderId); String schemaVersion(); }
  public static final class OrderAnalytics {
    private final OrderDataProduct product; public OrderAnalytics(OrderDataProduct p){this.product=p;}
    public long total(String orderId){ return product.byId(orderId).totalMinor(); }
  }
}

Modul 22 Data Lakehouse Architecture Offene, kostengünstige Datenspeicherung wird mit Transaktionen, Schemaevolution und analytischen Tabellen kombiniert.

Data Lakehouse Architecture

Geeignet

Analytik über große strukturierte und semistrukturierte Datenmengen

Leitplanke

Dateiformat allein ersetzt keine Governance, Katalogisierung oder Datenqualität

Alternative

Warehouse plus separater Data Lake

Abhängigkeitsfluss

Ingest -> Bronze -> Silver -> Gold Table

Migrationspfad

Einen klaren Datensatz mit Qualitätsstufen, Katalog und reproduzierbarer Transformation pilotieren

Testfokus

Schemaevolution, Deduplizierung, Reproduzierbarkeit und Zugriff prüfen

DataLakehouseArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.*;
// Architecture Pattern: Data Lakehouse
// Zweck: Rohdaten über explizite Qualitätsstufen in ein kuratiertes Tabellenmodell überführen.
public final class DataLakehouseArchitectureModule {
  public record RawOrder(String id,String total){}
  public record CuratedOrder(String id,long totalMinor){}
  public static final class SilverTransformer {
    public CuratedOrder transform(RawOrder raw){ return new CuratedOrder(raw.id(), Long.parseLong(raw.total())); }
    public List<CuratedOrder> transformAll(List<RawOrder> rows){ return rows.stream().map(this::transform).toList(); }
  }
}

Modul 23 Lambda Architecture Batch- und Speed-Layer berechnen gemeinsam ein Lesemodell für vollständige Historie und geringe Latenz.

Lambda Architecture

Geeignet

Analytik mit historischer Korrektheit und sehr schneller Aktualisierung

Leitplanke

Doppelte Geschäftslogik in Batch und Stream erhöht Wartungskosten

Alternative

Kappa Architecture

Abhängigkeitsfluss

Event Log -> Batch Layer + Speed Layer -> Serving View

Migrationspfad

Gemeinsames Ereignismodell definieren, Lesemodell messen und Doppelimplementierung bewusst begrenzen

Testfokus

Gleichheit der Batch- und Speed-Ergebnisse sowie Rebuild testen

LambdaArchitectureModule.java
package com.aydinsude.workbench.architecture;
// Architecture Pattern: Lambda Architecture
// Zweck: Historische Batch-Sicht und schnelle Delta-Sicht kontrolliert kombinieren.
public final class LambdaArchitectureModule {
  public record Metric(long batchValue,long speedDelta){ public long current(){ return batchValue + speedDelta; } }
  public interface BatchView { long value(String key); }
  public interface SpeedView { long delta(String key); }
  public static final class ServingView {
    private final BatchView batch; private final SpeedView speed;
    public ServingView(BatchView b,SpeedView s){batch=b;speed=s;}
    public Metric metric(String key){ return new Metric(batch.value(key),speed.delta(key)); }
  }
}

Modul 24 Kappa Architecture Ein unveränderlicher Ereignisstrom und eine Stream-Pipeline erzeugen alle aktuellen und neu aufgebauten Sichten.

Kappa Architecture

Geeignet

Ereigniszentrierte Systeme mit beherrschbarer Stream-Logik

Leitplanke

Reprocessing, Schemaänderungen und Zustandsspeicher müssen betrieblich beherrscht werden

Alternative

Lambda Architecture

Abhängigkeitsfluss

Event Log -> Stream Processor -> Materialized View

Migrationspfad

Einen Lesefall aus dem Ereignislog reproduzierbar aufbauen und Replay operationalisieren

Testfokus

Live-Verarbeitung und vollständiges Replay müssen identische Sichten liefern

KappaArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.*;
// Architecture Pattern: Kappa Architecture
// Zweck: Live-Verarbeitung und Rebuild über dieselbe Ereignisfunktion ausführen.
public final class KappaArchitectureModule {
  public sealed interface Event permits OrderPlaced,OrderCancelled {}
  public record OrderPlaced(String id,long totalMinor) implements Event {}
  public record OrderCancelled(String id) implements Event {}
  public static final class Projection {
    private final Map<String,Long> totals=new HashMap<>();
    public void apply(Event event){ if(event instanceof OrderPlaced p) totals.put(p.id(),p.totalMinor()); else if(event instanceof OrderCancelled c) totals.remove(c.id()); }
    public Map<String,Long> snapshot(){ return Map.copyOf(totals); }
  }
}
Kapitel 5 Actor Model, Parallelität und verteilte Koordination6 Architekturmodelle

Sechs abschließende Architekturentscheidungen für hochparallele, reaktive, verteilte und föderierte Systeme.

Architekturabschnitt 5

Enterprise Architecture Explorer

Sechs abschließende Architekturentscheidungen für hochparallele, reaktive, verteilte und föderierte Systeme.

Fachlicher Lernpfad

Grundlage → Entscheidungskriterien → Refactoring-Pfad → ausführbare Referenz → Einsatzgrenzen

Modul 25 Actor Model Architecture Isolierte Zustände und asynchrone Nachrichten reduzieren gemeinsam veränderlichen Zustand in hochparallelen Systemen.

Actor Model Architecture

Geeignet

Viele unabhängige, zustandsbehaftete Einheiten mit hoher Parallelität

Leitplanke

Mailbox-Überlastung, Nachrichtenduplikate und Lebenszyklus müssen explizit kontrolliert werden

Alternative

Thread-per-request oder klassische Executor-Services

Abhängigkeitsfluss

Sender -> Mailbox -> Actor State

Migrationspfad

Einen abgegrenzten zustandsbehafteten Prozess als Actor modellieren und Nachrichtenvertrag stabilisieren

Testfokus

Deterministische Zustandsübergänge, Reihenfolge, Duplikate und Backpressure

ActorModelArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.concurrent.*;
// Architecture Pattern: Actor Model
// Zweck: Veränderlichen Zustand hinter einer seriell verarbeiteten Mailbox kapseln.
public final class ActorModelArchitectureModule {
  public sealed interface Message permits Reserve,Release {}
  public record Reserve(int quantity) implements Message {}
  public record Release(int quantity) implements Message {}
  public static final class InventoryActor implements AutoCloseable {
    private final ExecutorService mailbox=Executors.newSingleThreadExecutor();
    private int available;
    public InventoryActor(int initial){ available=initial; }
    public CompletableFuture<Integer> tell(Message message){
      return CompletableFuture.supplyAsync(() -> {
        if(message instanceof Reserve r){ if(r.quantity()>available) throw new IllegalStateException("stock"); available-=r.quantity(); }
        else if(message instanceof Release r){ available+=r.quantity(); }
        return available;
      },mailbox);
    }
    public void close(){ mailbox.shutdown(); }
  }
}

Modul 26 Reactive Architecture Nicht blockierende Verarbeitung, Backpressure und Fehlertoleranz halten Systeme auch unter Last reaktionsfähig.

Reactive Architecture

Geeignet

I/O-intensive Systeme mit schwankender Last und strengen Latenzzielen

Leitplanke

Reactive APIs ohne Ende-zu-Ende-Backpressure verschieben nur den Engpass

Alternative

Klassische synchrone Architektur mit begrenzten Pools

Abhängigkeitsfluss

Publisher -> Demand -> Subscriber

Migrationspfad

Einen Engpass messen, asynchronen Vertrag definieren und Kapazitätsgrenzen explizit machen

Testfokus

Demand-Steuerung, Timeout, Abbruch, Fehlerpfade und Lastgrenzen

ReactiveArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;
// Architecture Pattern: Reactive Architecture
// Zweck: Datenfluss mit expliziter Nachfrage und Backpressure modellieren.
public final class ReactiveArchitectureModule {
  public static final class OrderPublisher extends SubmissionPublisher<String> {
    public void publish(String orderId){ submit(orderId); }
  }
  public static final class BoundedSubscriber implements Flow.Subscriber<String> {
    private Flow.Subscription subscription; private int processed;
    public void onSubscribe(Flow.Subscription s){ subscription=s; s.request(1); }
    public void onNext(String item){ processed++; subscription.request(1); }
    public void onError(Throwable error){ }
    public void onComplete(){ }
    public int processed(){ return processed; }
  }
}

Modul 27 Event Streaming Architecture Dauerhafte geordnete Ereignisströme verbinden Produzenten, zustandsbehaftete Verarbeitung und Materialized Views.

Event Streaming Architecture

Geeignet

Kontinuierliche Fachereignisse, Replays und mehrere unabhängige Konsumenten

Leitplanke

Schlüsselwahl, Schemaevolution, Reihenfolge und genau-einmalige Wirkung müssen beherrscht werden

Alternative

Message Queue oder klassische Event-Driven Architecture

Abhängigkeitsfluss

Producer -> Partitioned Log -> Stream Processor -> View

Migrationspfad

Einen Ereignisstrom mit stabilem Schlüssel und idempotenter Projektion pilotieren

Testfokus

Replay, Partitionierung, Schemaänderungen, Duplikate und Lag

EventStreamingArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.*;
// Architecture Pattern: Event Streaming Architecture
// Zweck: Unveränderliche Fachereignisse in reproduzierbare Projektionen überführen.
public final class EventStreamingArchitectureModule {
  public sealed interface Event permits OrderPlaced,OrderCancelled {}
  public record OrderPlaced(String orderId,long totalMinor) implements Event {}
  public record OrderCancelled(String orderId) implements Event {}
  public static final class OrderProjection {
    private final Map<String,Long> totals=new HashMap<>();
    public void apply(Event event){
      if(event instanceof OrderPlaced p) totals.put(p.orderId(),p.totalMinor());
      else if(event instanceof OrderCancelled c) totals.remove(c.orderId());
    }
    public Map<String,Long> snapshot(){ return Map.copyOf(totals); }
  }
}

Modul 28 Edge Computing Architecture Verarbeitung nahe an Geräten und Nutzern reduziert Latenz, Bandbreite und Abhängigkeit von zentralen Diensten.

Edge Computing Architecture

Geeignet

IoT, Filialen, Produktion oder globale Anwendungen mit Offline-Anforderungen

Leitplanke

Datenkonsistenz, Geräteverwaltung, Security und Update-Strategie werden komplexer

Alternative

Zentrale Cloud-Verarbeitung

Abhängigkeitsfluss

Device -> Edge Node -> Cloud Control Plane

Migrationspfad

Einen latenzkritischen Entscheidungsfall lokal ausführen und Synchronisationsvertrag definieren

Testfokus

Offline-Betrieb, Konflikte, sichere Updates, Telemetrie und Wiederanlauf

EdgeComputingArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.time.*;
// Architecture Pattern: Edge Computing Architecture
// Zweck: Latenzkritische Entscheidung lokal treffen und später synchronisieren.
public final class EdgeComputingArchitectureModule {
  public record SensorReading(String deviceId,double value,Instant measuredAt) {}
  public record EdgeDecision(boolean alert,String reason) {}
  public static final class EdgeRule {
    private final double threshold; public EdgeRule(double threshold){ this.threshold=threshold; }
    public EdgeDecision evaluate(SensorReading reading){
      return reading.value()>threshold ? new EdgeDecision(true,"threshold") : new EdgeDecision(false,"ok");
    }
  }
  public interface CloudSyncPort { void enqueue(SensorReading reading,EdgeDecision decision); }
}

Modul 29 Federated Architecture Autonome Domänen oder Plattformen bleiben unabhängig und kooperieren über gemeinsame Verträge und Governance.

Federated Architecture

Geeignet

Große Organisationen mit eigenständigen Domänen, Regionen oder Unternehmen

Leitplanke

Zu viel Autonomie ohne Standards erzeugt inkompatible Silos und doppelte Fähigkeiten

Alternative

Zentralisierte Plattform oder Shared Database

Abhängigkeitsfluss

Domain Node <-> Contract Hub <-> Domain Node

Migrationspfad

Gemeinsamen Minimalvertrag, Ownership und Konformitätstests für einen domänenübergreifenden Prozess etablieren

Testfokus

Vertragskompatibilität, Versionierung, Teilverfügbarkeit und Governance

FederatedArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.*;
// Architecture Pattern: Federated Architecture
// Zweck: Autonome Domänen über einen kleinen versionierten Vertrag integrieren.
public final class FederatedArchitectureModule {
  public record CustomerReference(String domain,String externalId) {}
  public interface CustomerDirectory { Optional<CustomerReference> resolve(String email); String contractVersion(); }
  public static final class FederationGateway {
    private final List<CustomerDirectory> directories;
    public FederationGateway(List<CustomerDirectory> directories){ this.directories=List.copyOf(directories); }
    public Optional<CustomerReference> resolve(String email){
      return directories.stream().map(d->d.resolve(email)).flatMap(Optional::stream).findFirst();
    }
  }
}

Modul 30 Shared-Nothing Architecture Jeder Knoten besitzt Rechenleistung und Datenpartition; horizontale Skalierung vermeidet zentrale Engpässe.

Shared-Nothing Architecture

Geeignet

Sehr große Datenmengen oder Workloads mit natürlicher Partitionierung

Leitplanke

Hotspots, Rebalancing und domänenübergreifende Transaktionen müssen vermieden oder explizit gelöst werden

Alternative

Shared Database Cluster

Abhängigkeitsfluss

Routing Key -> Independent Shard -> Local State

Migrationspfad

Einen stabilen Partitionierungsschlüssel wählen und einen isolierten Workload ohne Cross-Shard-Transaktion migrieren

Testfokus

Routing, Rebalancing, Hot Keys, Ausfall einzelner Shards und Datenlokalität

SharedNothingArchitectureModule.java
package com.aydinsude.workbench.architecture;
import java.util.*;
// Architecture Pattern: Shared-Nothing Architecture
// Zweck: Anfragen deterministisch auf unabhängige Datenpartitionen verteilen.
public final class SharedNothingArchitectureModule {
  public interface Shard { void store(String key,String value); Optional<String> load(String key); }
  public static final class ShardRouter {
    private final List<Shard> shards; public ShardRouter(List<Shard> shards){ if(shards.isEmpty()) throw new IllegalArgumentException("shards"); this.shards=List.copyOf(shards); }
    private Shard shard(String key){ return shards.get(Math.floorMod(key.hashCode(),shards.size())); }
    public void store(String key,String value){ shard(key).store(key,value); }
    public Optional<String> load(String key){ return shard(key).load(key); }
  }
}
⌂ Cockpit