Add OrderManagerInterface to Manager example; type all dependencies on interfaces
This commit is contained in:
+33
-20
@@ -132,11 +132,11 @@ namespace App\Logic\Sales\Order\Query;
|
||||
use App\Logic\Common\UseCaseInterface;
|
||||
use App\Logic\Sales\Order\Dto\GetOrdersRequest;
|
||||
use App\Logic\Sales\Order\Dto\GetOrdersResponse;
|
||||
use App\Logic\Sales\Order\Manager\OrderManager;
|
||||
use App\Logic\Sales\Order\Manager\OrderManagerInterface;
|
||||
|
||||
readonly class GetOrdersQuery implements UseCaseInterface
|
||||
{
|
||||
public function __construct(private OrderManager $orderManager) {}
|
||||
public function __construct(private OrderManagerInterface $orderManager) {}
|
||||
|
||||
public function execute(mixed $request): GetOrdersResponse
|
||||
{
|
||||
@@ -151,16 +151,27 @@ readonly class GetOrdersQuery implements UseCaseInterface
|
||||
}
|
||||
```
|
||||
|
||||
#### Manager (Read + Cache)
|
||||
#### Manager Interface (Logic Layer)
|
||||
```php
|
||||
namespace App\Logic\Sales\Order\Manager;
|
||||
|
||||
use App\Data\Sales\Order\Provider\OrderProvider;
|
||||
interface OrderManagerInterface
|
||||
{
|
||||
public function findOrders(array $filters, int $page): array;
|
||||
public function invalidateCache(): void;
|
||||
}
|
||||
```
|
||||
|
||||
readonly class OrderManager
|
||||
#### Manager Implementierung (Read + Cache)
|
||||
```php
|
||||
namespace App\Logic\Sales\Order\Manager;
|
||||
|
||||
use App\Logic\Sales\Order\OrderProviderInterface;
|
||||
|
||||
readonly class OrderManager implements OrderManagerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private OrderProvider $orderProvider,
|
||||
private OrderProviderInterface $orderProvider,
|
||||
// private CacheInterface $cache, <-- Symfony/PSR-6 Cache (injected via DI)
|
||||
) {}
|
||||
|
||||
@@ -276,12 +287,12 @@ 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\Manager\OrderManager;
|
||||
use App\Logic\Sales\Order\Manager\OrderManagerInterface;
|
||||
|
||||
readonly class CreateOrderUseCase implements UseCaseInterface
|
||||
{
|
||||
public function __construct(
|
||||
private OrderManager $orderManager,
|
||||
private OrderManagerInterface $orderManager,
|
||||
// TransactionManager ggf. für Multi-Processor-Szenarien
|
||||
) {}
|
||||
|
||||
@@ -417,28 +428,28 @@ interface TransactionManagerInterface
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Anwendung im UseCase (`src/Logic`)
|
||||
Der UseCase nutzt den TransactionManager, um sicherzustellen, dass entweder alle oder keine Änderungen persistiert werden (All-or-Nothing).
|
||||
#### Anwendung im UseCase (`src/Logic`)
|
||||
Der UseCase nutzt den TransactionManager, um sicherzustellen, dass entweder alle oder keine Änderungen persistiert werden (All-or-Nothing). Die Orchestrierung zwischen Managern erfolgt innerhalb der Transaktions-Closure.
|
||||
|
||||
```php
|
||||
readonly class CreateOrderUseCase implements UseCaseInterface
|
||||
{
|
||||
public function __construct(
|
||||
private TransactionManagerInterface $transactionManager,
|
||||
private OrderProcessorInterface $orderProcessor,
|
||||
private StockProcessorInterface $stockProcessor
|
||||
private OrderManager $orderManager,
|
||||
private StockManager $stockManager
|
||||
) {}
|
||||
|
||||
public function execute(mixed $request): CreateOrderResponse
|
||||
{
|
||||
return $this->transactionManager->transactional(function() use ($request) {
|
||||
// 1. Produktbestand reduzieren
|
||||
$this->stockProcessor->reduceStock($request->items);
|
||||
|
||||
// 2. Bestellung anlegen
|
||||
$order = $this->orderProcessor->save($request->toModel());
|
||||
|
||||
return new CreateOrderResponse(orderId: $order->id);
|
||||
// 1. Produktbestand reduzieren (Manager orchestriert Processor + Cache)
|
||||
$this->stockManager->reduceStockForOrder($request->items);
|
||||
|
||||
// 2. Bestellung anlegen (Manager orchestriert Processor + Cache)
|
||||
$order = $this->orderManager->createOrder($request);
|
||||
|
||||
return new CreateOrderResponse(orderId: $order.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -466,9 +477,11 @@ readonly class DoctrineTransactionManager implements TransactionManagerInterface
|
||||
|
||||
### Vorteile
|
||||
- **Kein Leaking**: Die Logic Layer weiß nicht, dass Doctrine verwendet wird.
|
||||
- **Atomarität**: Mehrere Processor können konsistent in einer Transaktion kombiniert werden.
|
||||
- **Atomarität**: Mehrere Manager können konsistent in einer Transaktion orchestriert werden.
|
||||
- **Testbarkeit**: Der TransactionManager kann in Unit Tests einfach durch einen Mock ersetzt werden, der den Closure direkt ausführt.
|
||||
|
||||
Die Manager-Konzepte werden in Sektion 3 (Write Pattern) detailliert beschrieben. Die UseCases arbeiten auf Managern, die ihrerseits Processors aufrufen.
|
||||
|
||||
## 6. Entity vs. Business Model (`src/Data` $\rightarrow$ `src/Logic`)
|
||||
|
||||
Um die Geschäftslogik vollständig vom Framework und dem ORM zu entkoppeln, wird eine strikte Trennung zwischen Persistenz-Objekten (Entities) und Domänen-Objekten (Business Models) eingeführt.
|
||||
|
||||
Reference in New Issue
Block a user