Короткий формат запитання
Чи в межах найкращих практик 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;
}
}
Це прийнятий спосіб впровадження вільних синтаксисів в Entities, не порушуючи основних принципів DDD та OOP? Мені це здається прекрасним, оскільки ми відкриваємо лише сервісний рівень, а не інфраструктурний рівень (який вкладається в службу)