Eine Spielwiese für Architektur-Experimente - ein minimal lauffähiger Prototyp eines Musikplayers, der als Testbed für moderne Software-Architektur-Patterns dient.
Was der Musikplayer macht:
-
Benutzerregistrierung: Neue Benutzer können sich registrieren und werden automatisch eingeloggt (kein expliziter Login/Logout-Prozess)
-
MP3-Upload & Wiedergabe: Benutzer können MP3-Dateien hochladen und abspielen
-
Live-Scoreboard: Benutzer erhalten Echtzeit-Benachrichtigungen (via Server-Sent Events), wenn jemand zum Top-Scorer wird
Architektur-Demonstration:
Der Prototyp zeigt das Zusammenspiel von 3 Komponenten über Events in einem Modulithen:
-
👤 User-Komponente: Registrierung, automatischer Login, Event-Empfang via SSE
-
🎵 Musicplayer-Komponente: MP3-Upload, Wiedergabe, sendet "NeuesLiedWurdeAngelegt" Events
-
🏆 Scoreboard-Komponente: Zählt Lieder pro User, ermittelt Top-Scorer, sendet "BenutzerIstNeuerTopScorer" Events
Warum ein Musikplayer? Genug fachliche Komplexität für realistische Architektur-Entscheidungen, aber einfach genug, um sich auf die technischen Aspekte zu konzentrieren.
Experimenteller Rahmen:
-
Minimal lauffähiger Prototyp mit ausreichend Logik für Experimente
-
Labor für Architektur-Patterns und Testing-Strategien
-
Dokumentation von Erkenntnissen und gescheiterten Ansätzen
-
🏗️ Modulith mit Event-Driven Design - 3 lose gekoppelte Komponenten über Events
-
🧪 Clean Architecture - Domain, Use Cases, Adapters klar getrennt
-
🥒 Component-Testing statt Unit-Tests - Cucumber BDD-Tests mit Fake Adapters
-
⚡ Parallele Tests - Tenant-basierte Isolation ohne Datenbankreinigung
# Voraussetzungen: Java 21, Docker
sdk install java 21.0.2-tem && sdk use java 21.0.2-tem
# Datenbank aufsetzen und Tests laufen lassen
./mvnw clean verify
# Anwendung starten
./mvnw docker-compose:up@run-docker -pl services/acme
./mvnw spring-boot:run -pl services/acmeAusführliche Anleitung: → Development Setup Guide
Status: Erfolgreich implementiert
Problem: Langsame, sequentielle Integrationstests durch Datenbankreinigung Lösung: Tenant-Parameter in allen Use Cases und Repositories Ergebnis: Alle Tests können parallel in eigenen "Tenants" arbeiten
-
UUID am Szenarioanfang im Test
-
Alle Use Case Commands um "Tenant" Parameter erweitern (Default "1" oder "GLOBAL")
-
Repos/Indizes nach Tenant-Id umbauen
-
AfterAll: Löschen aller Testdaten anhand des Tenants
Problem: Wie können Tests am Ende komplexer fachlicher Prozesse geschrieben werden?
Ansätze in Evaluation:
-
Fachlich korrekte Testdatenbuilder
-
⚠️ Gefahr der Re-Implementierung der Businesslogik im Testcode -
✅ Wiederverwendung von Businesslogik möglich
-
❌ Erzwingt Datenbankzugriff an Use Cases vorbei
-
-
Snapshot/Backup-Restore für Szenarien
-
✅ Szenario 1 laufen lassen → snapshotted → in Szenario 2 wiederverwenden
-
❌ Abhängigkeiten zwischen Szenarien entstehen
-
-
Prozessorientierte Testszenarien
-
Statt einzelner Features: komplette User-Journeys testen
-
Beispiel: "User registriert sich → lädt MP3 hoch → spielt ab" in einem Szenario
-
Test-Innovation: Keine klassischen Unit-Tests, sondern Komponententests mit hoher Abdeckung! Details: → Component Testing Konzept
✅ Erfolgreich implementiert:
-
JOOQ statt JPA/Hibernate - Type-safe SQL ohne ORM-Overhead
-
Cucumber Component-Tests statt klassischer Unit-Tests - BDD-Tests mit Fake Adapters
-
Tenant-basierte Test-Isolation - Parallele, unabhängige Tests ohne Datenbankreinigung
-
HTMX + SSE - Moderne Web-UI ohne JavaScript-Framework
❌ Verworfene Ansätze: Spring Native (zu unreif, siehe ADR)
-
🚀 Setup Guide - Ausführliche Entwicklungsumgebung
-
🧪 Component Testing - Testing-Strategie im Detail
-
📋 Architecture Decision Records - Alle Architektur-Entscheidungen
-
Spring Native Evaluation - Warum wir es verworfen haben
-
Testing Framework Vergleich - Cucumber vs. JUnit vs. Spock
-
Persistenz-Framework Entscheidung - JOOQ vs. JPA
💡 Für Entwickler: Dieses Projekt ist bewusst als Experimentierfeld konzipiert. Erkenntnisse, gescheiterte Ansätze und Learnings sind genauso wertvoll wie funktionierende Lösungen!
