Краткий формат вопроса
Находится ли в лучших практиках DDD и OOP внедрение служб при вызовах методов сущностей?
Пример длинного формата
Допустим, у нас есть классический случай Order-LineItems в DDD, где у нас есть объект домена, называемый заказом, который также действует как совокупный корень, и этот объект состоит не только из его объектов-значений, но и из коллекции элементов строки Сущности.
Предположим, нам нужен свободный синтаксис в нашем приложении, чтобы мы могли сделать что-то вроде этого (отметив синтаксис в строке 2, где мы вызываем getLineItems
метод):
$order = $orderService->getOrderByID($orderID);
foreach($order->getLineItems($orderService) as $lineItem) {
...
}
Мы не хотим внедрять какие-либо LineItemRepository в OrderEntity, поскольку это является нарушением нескольких принципов, о которых я могу думать. Но беглость синтаксиса - это то, что нам действительно нужно, потому что его легко читать и поддерживать, а также тестировать.
Рассмотрим следующий код, отметив метод getLineItems
в 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;
}
}
Является ли это приемлемым способом реализации свободного синтаксиса в сущностях без нарушения основных принципов DDD и ООП? Мне кажется, это нормально, так как мы показываем только уровень сервиса, а не уровень инфраструктуры (который вложен в сервис)