docs: consolidate module communication, handler paths, manager granularity, mapping factory pattern, and testing guidelines
This commit is contained in:
+7
-5
@@ -16,7 +16,7 @@ Die Anwendung ist in drei strikt getrennte Layer unterteilt:
|
||||
- **Komponenten**:
|
||||
- **UseCases / Workflows**: Repräsentieren eine spezifische Geschäftsaktion (z.B. `CreateUserUseCase`). Nutzen DTOs für den Datentransfer.
|
||||
- **BusinessQueries**: Spezifische Abfragen für geschäftsrelevante Daten.
|
||||
- **Manager**: Orchestratoren, die z.B. Caching-Strategien implementieren und zwischen verschiedenen Providern/Processoren vermitteln.
|
||||
- **Manager**: Steuert Lese- und Schreibzugriffe auf ein einzelnes Business Model (z. B. Caching via "Cache-Aside"). Komplexe Aggregationen über mehrere Domänen hinweg werden bewusst vermieden, um Kopplung zu reduzieren.
|
||||
- **Models**: Kernlogik-Objekte zur internen Verarbeitung innerhalb der Logic Layer.
|
||||
- **Provider / Processor Interfaces**: Definieren den Datenaustausch mit der Data Layer und ermöglichen Dependency Inversion.
|
||||
- **Regel**: Ist unabhängig von der UI Layer und definiert die Anforderungen an die Data Layer über Interfaces.
|
||||
@@ -40,12 +40,13 @@ Die Anwendung ist in drei strikt getrennte Layer unterteilt:
|
||||
1. **Eintrittspunkt**: Die UI Layer ruft immer einen UseCase, Workflow oder eine BusinessQuery in der Logic Layer auf.
|
||||
2. **Orchestrierung**: Manager in der Logic Layer organisieren den Zugriff (z.B. Cache-Check) und delegieren die eigentliche Arbeit an Provider- oder Processor-Interfaces der Data Layer.
|
||||
3. **Entkopplung**: Die Logic Layer sollte idealerweise gegen Interfaces der Data Layer programmieren, um die Austauschbarkeit der Datenquelle zu gewährleisten.
|
||||
4. **Modulkapselung (Adapter)**: Module kommunizieren nicht direkt mit den internen Strukturen anderer Module. Wenn ein UseCase aus Modul A eine Fähigkeit von Modul B benötigt, definiert Modul A ein eigenes Adapter-Interface. Die Implementation von Modul B wird via Dependency Inversion im Container auf dieses Interface gemappt. Dies verhindert enge Kopplung und vereinfacht Tests entscheidend.
|
||||
|
||||
## 3. Validierungsstrategie
|
||||
|
||||
Das Prinzip lautet: Jeder Layer validiert das, was er in seinem Kontext validieren kann.
|
||||
Das Prinzip lautet: Jeder Layer validiert das, was er in seinem Kontext validieren kann. Eine detaillierte Beschreibung mit Layer-Verantwortlichkeiten und Codebeispielen findet sich in [architektur-patterns.md Sektion 4](./architektur-patterns.md#4-validierungsstrategie-mehrschichtig).
|
||||
|
||||
- **UI Layer**: Syntaktische Validierung (z. B. Format, Pflichtfelder, Typen). Ziel ist es, ungültigen Input so früh wie möglich abzufangen.
|
||||
- **UI Layer**: Syntaktische Validierung (z. B. Format, Pflichtfelder, Typen).
|
||||
- **Logic Layer**: Semantische/Business-Validierung (z. B. Logik-Checks gegen Geschäftsregeln, Berechtigungen).
|
||||
- **Data Layer**: Technische Integrität (z. B. Unique-Constraints der Datenbank, korrekte Datentypen in der Persistenzschicht).
|
||||
|
||||
@@ -70,8 +71,9 @@ Zur Entkopplung zeitintensiver Prozesse wird ein Message-Bus eingesetzt. Dabei g
|
||||
- **Dispatcher Entkopplung**: Die Logic Layer nutzt ein eigenes Interface (z. B. `EventPublisherInterface`), um Nachrichten zu versenden. Die technische Implementierung dieses Interfaces erfolgt außerhalb der Logikschicht (Framework-Bridge), sodass die Business-Logik unabhängig vom Symfony Messenger bleibt.
|
||||
|
||||
### Message Handler
|
||||
- **Ort**: Message-Handler befinden sich in der **UI Layer**.
|
||||
- **Rolle**: Da ein asynchroner Nachrichteneingang ein externer Eintrittspunkt ist, fungiert der Handler als Adapter. Er nimmt die Message entgegen und delegiert die eigentliche Verarbeitung an einen entsprechenden UseCase oder Workflow in der Logic Layer.
|
||||
- **Ort**: Message-Handler befinden sich in `src/UI/{Module}/Handlers/{Feature}/{Name}Handler.php`.
|
||||
- **One-to-One Prinzip**: Es gilt strikt eine Nachricht pro Handler. Jeder Handler bleibt schlank und übernimmt nur die Transformation der Message und delegiert sie an den korrekten UseCase oder Workflow.
|
||||
- **Rolle**: Da ein asynchroner Nachrichteneingang ein externer Eintrittspunkt ist, fungiert der Handler als Adapter. Er nimmt die Message entgegen und delegiert die eigentliche Verarbeitung an einen genau einem bestimmten UseCase oder Workflow in der Logic Layer.
|
||||
|
||||
## 6. Teststrategie & Symmetrie
|
||||
Um eine hohe Codequalität und Wartbarkeit zu gewährleisten, wird eine pyramidale Teststrategie verfolgt. Dabei gilt das Prinzip der **Symmetrie**: Die Verzeichnisstruktur unter `tests/` spiegelt exakt die Struktur von `src/` wider, um die Auffindbarkeit von Tests sicherzustellen.
|
||||
|
||||
Reference in New Issue
Block a user