diff --git a/architektur-patterns.md b/architektur-patterns.md index 9955cab..b39d174 100644 --- a/architektur-patterns.md +++ b/architektur-patterns.md @@ -109,12 +109,40 @@ Das Read Pattern beschreibt den Weg einer Datenabfrage von der UI bis zur Datenq - **Pfad**: `src/Logic/{Module}/{Feature}/Query/...` #### Manager (Logic Layer) -- **Zweck**: Steuert die Bereitstellung der Daten. Hier erfolgt primär die Cache-Logik ("Cache-Aside") und die Koordination von Providern. -- **Verantwortung**: Entscheidung, ob Daten aus dem Cache oder frisch vom Provider geladen werden müssen. +- **Zweck**: Steuert die Bereitstellung der Daten und koordiniert Schreibvorgänge. +- **Schnittstelle**: Besitzt ein eigenes Interface in der Logic Layer zur Gewährleistung von Testbarkeit und Austauschbarkeit. +- **Verantwortung**: + - Read: Entscheidung zwischen Cache (Cache-Aside) und Provider. + - Write: Triggerung der Cache-Invalidierung nach erfolgreichen Änderungen. +- **Zustand**: Strikt zustandslos (stateless). -#### Provider (Data Layer) -- **Zweck**: Führt die technische Abfrage gegen die Infrastruktur aus (DB, API). -- **Rückgabewert**: Liefert die **Kern-Business-Models** zurück, nicht notwendigerweise die technischen Entities der Datenbank. + +... +102: ### Der Datenfluss +103: `UI Layer` $\rightarrow$ **BusinessQuery** $\rightarrow$ **Manager** $\rightarrow$ **Provider** +104: +105: #### BusinessQuery (Logic Layer) +106: - **Zweck**: Dient als fachlicher Einstiegspunkt für Leseoperationen. Sie orchestriert Manager oder andere Queries, um ein Endresultat zu formen. +107: - **Struktur**: Implementiert das gleiche Muster wie UseCases (`execute()` Methode). +108: - **Input/Output**: Nutzt Request-DTOs (besonders für Filter und Pagination) und gibt Response-DTOs zurück. +109: - **Pfad**: `src/Logic/{Module}/{Feature}/Query/...` +110: +111: #### Manager (Logic Layer) +112: - **Zweck**: Steuert die Bereitstellung der Daten. Hier erfolgt primär die Cache-Logik ("Cache-Aside") und die Koordination von Providern. +113: - **Verantwortung**: Entscheidung, ob Daten aus dem Cache oder frisch vom Provider geladen werden müssen. +114: +115: #### Provider (Data Layer) +116: - **Zweck**: Führt die technische Abfrage gegen die Infrastruktur aus (DB, API). +117: - **Schnittstelle**: Die Provider-Interfaces liegen zwingend in der **Logic Layer**, um Dependency Inversion zu gewährleisten. +118: - **Rückgabewert**: Liefert ausschließlich **Kern-Business-Models** zurück. +119: - Einfache Listen $\rightarrow$ `array` (mit PHPDoc `@return Model[]`). +120: - Paginierten Listen $\rightarrow$ Ein Wrapper-Objekt (z. B. `PaginatedCollection`), das Daten und Metadaten enthält. +121: - **Fehlerbehandlung**: Wirft im Fehlerfall direkt **Domain-Exceptions**. +122: - **Parameter**: Nutzt für einfache Lookups primitive Typen (`string`, `int`), für komplexe Abfragen DTOs. +123: - **Granularität**: Ein Provider pro Business-Model. +124: +125: ### Code Beispiel +... ### Code Beispiel @@ -172,5 +200,56 @@ readonly class OrderProvider return []; } } + +## 3. Write Pattern (`src/Logic` $\rightarrow$ `src/Data`) + +Das Write Pattern definiert den Weg von einer Zustandsänderung hin zur Persistenz. Es stellt sicher, dass Schreiboperationen atomar erfolgen und die Integrität der Business-Models gewahrt bleibt. + +### Der Datenfluss +`UI Layer` $\rightarrow$ **UseCase** $\rightarrow$ **Manager** (optional) $\rightarrow$ **Processor** + +#### Processor (Data Layer) +- **Zweck**: Übernimmt die physische Persistierung eines Business-Models. +- **Schnittstelle**: Das `ProcessorInterface` liegt zwingend in der **Logic Layer** (Dependency Inversion). +- **Input**: Ein Business-Model. +- **Rückgabewert**: Das aktualisierte/neu erstellte Business-Model (z.B. zur Rückgabe von generierten IDs). +- **Fehlerbehandlung**: Wirft im Fehlerfall direkt **Domain-Exceptions**. +- **Strategie**: Verfolgt den "All or Nothing" Ansatz; die übergeordnete Transaktion wird vom UseCase gesteuert. +- **Granularität**: Fokus auf eine einzelne Entität pro Processor. + +### Code Beispiel + +#### Processor Interface & Implementierung +```php +namespace App\Logic\Sales\Order; + +use App\Logic\Sales\Order\Model\Order; + +interface OrderProcessorInterface +{ + public function save(Order $order): Order; + public function delete(string $id): void; +} + +// --- Data Layer --- +namespace App\Data\Sales\Order\Processor; + +use App\Logic\Sales\Order\OrderProcessorInterface; +use App\Logic\Sales\Order\Model\Order; + +readonly class OrderProcessor implements OrderProcessorInterface +{ + public function save(Order $order): Order + { + // Persistenz-Logik (DB/API) ... + return $order; // Hier ggf. mit generierter ID zurückgeben + } + + public function delete(string $id): void + { + // Lösch-Logik ... + } +} +``` ``` ```