Breve formato della domanda
È nelle migliori pratiche di DDD e OOP iniettare servizi nelle chiamate al metodo dell'entità?
Esempio di formato lungo
Supponiamo di avere il classico caso Order-LineItems in DDD, in cui abbiamo un'entità dominio denominata un ordine, che funge anche da radice aggregata e che l'entità è composta non solo dai suoi oggetti valore, ma anche da una raccolta di elementi pubblicitari Entità.
Supponiamo di voler sintassi fluida nella nostra applicazione, in modo da poter fare qualcosa del genere (notando la sintassi nella riga 2, dove chiamiamo il getLineItems
metodo):
$order = $orderService->getOrderByID($orderID);
foreach($order->getLineItems($orderService) as $lineItem) {
...
}
Non vogliamo iniettare alcun tipo di LineItemRepository in OrderEntity, poiché si tratta di una violazione di diversi principi a cui riesco a pensare. Ma la fluidità della sintassi è qualcosa che vogliamo davvero, perché è facile da leggere e mantenere, oltre che da testare.
Considera il codice seguente, notando il metodo getLineItems
in OrderEntity
:
interface IOrderService {
public function getOrderByID($orderID) : OrderEntity;
public function getLineItems(OrderEntity $orderEntity) : LineItemCollection;
}
class OrderService implements IOrderService {
private $orderRepository;
private $lineItemRepository;
public function __construct(IOrderRepository $orderRepository, ILineItemRepository $lineItemRepository) {
$this->orderRepository = $orderRepository;
$this->lineItemRepository = $lineItemRepository;
}
public function getOrderByID($orderID) : OrderEntity {
return $this->orderRepository->getByID($orderID);
}
public function getLineItems(OrderEntity $orderEntity) : LineItemCollection {
return $this->lineItemRepository->getLineItemsByOrderID($orderEntity->ID());
}
}
class OrderEntity {
private $ID;
private $lineItems;
public function getLineItems(IOrderServiceInternal $orderService) {
if(!is_null($this->lineItems)) {
$this->lineItems = $orderService->getLineItems($this);
}
return $this->lineItems;
}
}
È questo il modo accettato di implementare la sintassi fluida nelle Entità senza violare i principi fondamentali di DDD e OOP? A me sembra bene, poiché stiamo solo esponendo il livello di servizio, non il livello di infrastruttura (che è nidificato all'interno del servizio)