Format court de la question
Est-il conforme aux meilleures pratiques de DDD et OOP d'injecter des services sur les appels de méthode d'entité?
Exemple de format long
Disons que nous avons le cas classique Order-LineItems dans DDD, où nous avons une entité de domaine appelée une commande, qui agit également en tant que racine agrégée, et cette entité est composée non seulement de ses objets de valeur, mais également d'une collection d'éléments de ligne Entités.
Supposons que nous voulons une syntaxe fluide dans notre application, afin de pouvoir faire quelque chose comme ça (en notant la syntaxe à la ligne 2, où nous appelons la getLineItems
méthode):
$order = $orderService->getOrderByID($orderID);
foreach($order->getLineItems($orderService) as $lineItem) {
...
}
Nous ne voulons injecter aucune sorte de LineItemRepository dans OrderEntity, car c'est une violation de plusieurs principes auxquels je peux penser. Mais, la maîtrise de la syntaxe est quelque chose que nous voulons vraiment, car il est facile à lire et à maintenir, ainsi qu'à tester.
Considérez le code suivant, en notant la méthode getLineItems
dans 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;
}
}
Est-ce la façon acceptée de mettre en œuvre une syntaxe fluide dans les entités sans violer les principes fondamentaux de DDD et OOP? Pour moi, cela semble bien, car nous exposons uniquement la couche service, pas la couche infrastructure (qui est imbriquée dans le service)