From 9550cec73d29c96e7517bcd15e5b6962ca35f1dc Mon Sep 17 00:00:00 2001 From: Jens Date: Wed, 15 Jul 2026 19:18:07 +0200 Subject: [PATCH] feat: define UseCase pattern and directory structure --- architektur-patterns.md | 97 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 architektur-patterns.md diff --git a/architektur-patterns.md b/architektur-patterns.md new file mode 100644 index 0000000..d7ecddd --- /dev/null +++ b/architektur-patterns.md @@ -0,0 +1,97 @@ +# Architektur Patterns + +Diese Datei definiert die konkreten Implementierungsmuster für die verschiedenen Layer der Anwendung. + +## 1. UseCase Pattern (`src/Logic`) + +Das UseCase Pattern bildet das Herzstück der Business-Logik. Jeder Anwendungsfall wird als eigenständige Klasse implementiert, um eine klare Trennung der Verantwortlichkeiten und eine hohe Testbarkeit zu gewährleisten. + +### Struktur & Definition +- **Interface**: Alle UseCases müssen das `UseCaseInterface` implementieren. +- **Methode**: Die primäre Logik liegt in der Methode `execute()`. +- **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). +- **Fehlerbehandlung**: Business-Fehler werden über spezifische **Domain-Exceptions** signalisiert. + +### DTOs (Data Transfer Objects) +- **Typ**: Readonly-Klassen (PHP 8.2+). +- **Namenskonvention**: Suffix `Request` für Eingabe, `Response` für Ausgabe. +- **Typisierung**: Maximale native Typisierung; PHPDocs nur bei komplexen Types (z.B. Generics in Arrays). + +### Namenskonvention & Verzeichnisstruktur +- **Klassennamen**: Suffix `UseCase`. +- **Pfad**: `src/Logic/{Module}/{Feature}/{Typ}/...` + +**Beispiel-Struktur:** +- `src/Logic/Sales/Order/UseCase/CreateOrderUseCase.php` +- `src/Logic/Sales/Order/Dto/CreateOrderRequest.php` +- `src/Logic/Sales/Order/Dto/CreateOrderResponse.php` + +### Code Beispiel + +#### Interface +```php +namespace App\Logic\Common; + +/** + * @template TRequest + * @template TResponse + */ +interface UseCaseInterface +{ + /** + * @param TRequest $request + * @return TResponse|void + */ + public function execute(mixed $request): mixed; +} +``` + +#### Implementierung +```php +namespace App\Logic\Sales\Order\UseCase; + +use App\Logic\Common\UseCaseInterface; +use App\Logic\Sales\Order\Dto\CreateOrderRequest; +use App\Logic\Sales\Order\Dto\CreateOrderResponse; +use App\Logic\Sales\Order\Exception\InsufficientStockException; + +readonly class CreateOrderUseCase implements UseCaseInterface +{ + public function execute(mixed $request): CreateOrderResponse + { + if (!$request instanceof CreateOrderRequest) { + throw new \InvalidArgumentException('Invalid request type'); + } + + // Business Logik hier... + if ($this->stockTooLow()) { + throw new InsufficientStockException(); + } + + return new CreateOrderResponse(orderId: '123'); + } + + private function stockTooLow(): bool { return false; } +} +``` + +#### DTOs +```php +namespace App\Logic\Sales\Order\Dto; + +readonly class CreateOrderRequest +{ + public function __construct( + public string $customerId, + public array $items, + ) {} +} + +readonly class CreateOrderResponse +{ + public function __construct( + public string $orderId, + ) {} +} +```