Formato corto de pregunta
¿Está dentro de las mejores prácticas de DDD y OOP inyectar servicios en llamadas de método de entidad?
Ejemplo de formato largo
Supongamos que tenemos el clásico caso Order-LineItems en DDD, donde tenemos una Entidad de dominio llamada Order, que también actúa como Aggregate Root, y esa Entidad está compuesta no solo por sus Value Value, sino también una colección de Line Item Entidades
Supongamos que queremos una sintaxis fluida en nuestra aplicación, de modo que podamos hacer algo como esto (notando la sintaxis en la línea 2, donde llamamos al getLineItems
método):
$order = $orderService->getOrderByID($orderID);
foreach($order->getLineItems($orderService) as $lineItem) {
...
}
No queremos inyectar ningún tipo de LineItemRepository en OrderEntity, ya que es una violación de varios principios en los que puedo pensar. Pero, la fluidez de la sintaxis es algo que realmente queremos, porque es fácil de leer y mantener, además de probar.
Considere el siguiente código, anotando el método getLineItems
en 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;
}
}
¿Es esa la forma aceptada de implementar una sintaxis fluida en las entidades sin violar los principios básicos de DDD y OOP? A mí me parece bien, ya que solo estamos exponiendo la capa de servicio, no la capa de infraestructura (que está anidada dentro del servicio)