docs: enforce 3-4 dependency limit for UseCases and introduce Orchestrator pattern
This commit is contained in:
@@ -10,6 +10,52 @@ Das UseCase Pattern bildet das Herzstück der Business-Logik. Zusammen mit dem R
|
||||
- **Eingabe/Ausgabe**: Daten werden strikt über DTOs (Data Transfer Objects) ausgetauscht.
|
||||
- **Rückgabewert**: Ein UseCase gibt entweder ein Response-DTO zurück oder `void` (bei reinen Schreiboperationen). Die PHP-Signatur ist native typisiert, sodass zur Laufzeit keine `instanceof`-Prüfungen nötig sind.
|
||||
- **Fehlerbehandlung**: Business-Fehler werden über spezifische **Domain-Exceptions** signalisiert.
|
||||
- **Dependency Limitation**: Ein UseCase sollte maximal 3–4 Dependencies injizieren. Ab 5+ Dependencies wird dringend empfohlen, einen **Orchestrator** einzusetzen.
|
||||
|
||||
### Orchestrator Pattern (Optional für komplexe Koordination)
|
||||
Wenn ein UseCase die Zuständigkeit mehrerer Domänen abdeckt (z. B. `Sales`, `Stock` und `Accounting` gleichzeitig), sollte er diese Manager nicht einzeln injizieren.
|
||||
|
||||
- **Ort**: `src/Logic/{Module}/{Feature}/Orchestrator/`
|
||||
- **Zweck**: Bündelt mehrere Manager zu einer einzigen fachlichen Operation (z. B. `OrderFulfillmentOrchestrator`).
|
||||
- **Vorteil**: Reduziert den UseCase-Konstruktor auf eine einzige Abhängigkeit und isoliert komplexe Multi-Domain-Logik, was die Testbarkeit massiv verbessert.
|
||||
|
||||
```php
|
||||
// src/Logic/Sales/Order/Orchestrator/
|
||||
readonly class OrderFulfillmentOrchestrator
|
||||
{
|
||||
public function __construct(
|
||||
private OrderManagerInterface $orders,
|
||||
private StockManagerInterface $stock,
|
||||
private TransactionManagerInterface $transactions,
|
||||
) {}
|
||||
|
||||
public function fulfillOrder(CreateOrderRequest $request): Order
|
||||
{
|
||||
return $this->transactions->execute(function() use ($request) {
|
||||
if (!$this->stock->isSufficient($request->items)) {
|
||||
throw new InsufficientStockException();
|
||||
}
|
||||
// Business Model anlegen & persistieren
|
||||
$order = new Order(/* ... */);
|
||||
return $this->orders->create($order);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Der UseCase profitiert von der schlanken Injektion:
|
||||
readonly class CreateOrderUseCase {
|
||||
public function __construct(
|
||||
private OrderFulfillmentOrchestrator $orchestrator,
|
||||
private EventDispatcherInterface $eventDispatcher,
|
||||
) {}
|
||||
|
||||
public function execute(CreateOrderRequest $request): CreateOrderResponse {
|
||||
$order = $this->orchestrator->fulfillOrder($request);
|
||||
$this->eventDispatcher->dispatch(new OrderCreatedEvent(orderId: $order->id));
|
||||
return new CreateOrderResponse(orderId: $order->id);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DTOs (Data Transfer Objects)
|
||||
- **Typ**: Readonly-Klassen (PHP 8.2+).
|
||||
|
||||
Reference in New Issue
Block a user