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\Common\UseCaseInterface;
|
||||||
use App\Logic\Sales\Order\Dto\GetOrdersRequest;
|
use App\Logic\Sales\Order\Dto\GetOrdersRequest;
|
||||||
use App\Logic\Sales\Order\Dto\GetOrdersResponse;
|
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
|
readonly class GetOrdersQuery implements UseCaseInterface
|
||||||
{
|
{
|
||||||
public function __construct(private OrderManager $orderManager) {}
|
public function __construct(private OrderManagerInterface $orderManager) {}
|
||||||
|
|
||||||
public function execute(mixed $request): GetOrdersResponse
|
public function execute(mixed $request): GetOrdersResponse
|
||||||
{
|
{
|
||||||
@@ -151,16 +151,27 @@ readonly class GetOrdersQuery implements UseCaseInterface
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Manager (Read + Cache)
|
#### Manager Interface (Logic Layer)
|
||||||
```php
|
```php
|
||||||
namespace App\Logic\Sales\Order\Manager;
|
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(
|
public function __construct(
|
||||||
private OrderProvider $orderProvider,
|
private OrderProviderInterface $orderProvider,
|
||||||
// private CacheInterface $cache, <-- Symfony/PSR-6 Cache (injected via DI)
|
// 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\Common\UseCaseInterface;
|
||||||
use App\Logic\Sales\Order\Dto\CreateOrderRequest;
|
use App\Logic\Sales\Order\Dto\CreateOrderRequest;
|
||||||
use App\Logic\Sales\Order\Dto\CreateOrderResponse;
|
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
|
readonly class CreateOrderUseCase implements UseCaseInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private OrderManager $orderManager,
|
private OrderManagerInterface $orderManager,
|
||||||
// TransactionManager ggf. für Multi-Processor-Szenarien
|
// TransactionManager ggf. für Multi-Processor-Szenarien
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -417,28 +428,28 @@ interface TransactionManagerInterface
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2. Anwendung im UseCase (`src/Logic`)
|
#### Anwendung im UseCase (`src/Logic`)
|
||||||
Der UseCase nutzt den TransactionManager, um sicherzustellen, dass entweder alle oder keine Änderungen persistiert werden (All-or-Nothing).
|
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
|
```php
|
||||||
readonly class CreateOrderUseCase implements UseCaseInterface
|
readonly class CreateOrderUseCase implements UseCaseInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private TransactionManagerInterface $transactionManager,
|
private TransactionManagerInterface $transactionManager,
|
||||||
private OrderProcessorInterface $orderProcessor,
|
private OrderManager $orderManager,
|
||||||
private StockProcessorInterface $stockProcessor
|
private StockManager $stockManager
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function execute(mixed $request): CreateOrderResponse
|
public function execute(mixed $request): CreateOrderResponse
|
||||||
{
|
{
|
||||||
return $this->transactionManager->transactional(function() use ($request) {
|
return $this->transactionManager->transactional(function() use ($request) {
|
||||||
// 1. Produktbestand reduzieren
|
// 1. Produktbestand reduzieren (Manager orchestriert Processor + Cache)
|
||||||
$this->stockProcessor->reduceStock($request->items);
|
$this->stockManager->reduceStockForOrder($request->items);
|
||||||
|
|
||||||
// 2. Bestellung anlegen
|
// 2. Bestellung anlegen (Manager orchestriert Processor + Cache)
|
||||||
$order = $this->orderProcessor->save($request->toModel());
|
$order = $this->orderManager->createOrder($request);
|
||||||
|
|
||||||
return new CreateOrderResponse(orderId: $order->id);
|
return new CreateOrderResponse(orderId: $order.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,9 +477,11 @@ readonly class DoctrineTransactionManager implements TransactionManagerInterface
|
|||||||
|
|
||||||
### Vorteile
|
### Vorteile
|
||||||
- **Kein Leaking**: Die Logic Layer weiß nicht, dass Doctrine verwendet wird.
|
- **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.
|
- **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`)
|
## 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.
|
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