질문의 짧은 형식
엔티티 메소드 호출에 서비스를 삽입하는 것이 DDD 및 OOP의 우수 사례 내에 있습니까?
긴 형식 예
DDD에 고전적인 Order-LineItems 사례가 있다고 가정합니다. 여기에서 Order라는 도메인 엔터티가 있으며,이 루트는 또한 Root Root 역할을하며 엔터티는 Value Objects뿐만 아니라 Line Item의 컬렉션으로 구성됩니다. 엔티티.
응용 프로그램에서 유창한 구문을 원한다고 가정하면 다음과 같이 할 수 있습니다 ( getLineItems
방법 을 호출하는 2 행의 구문에 유의하십시오 ).
$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 및 OOP의 핵심 원칙을 위반하지 않고 엔터티에서 유창한 구문을 구현하는 것이 허용되는 방법입니까? 우리에게는 인프라 계층 (서비스 내에 중첩되어 있음)이 아닌 서비스 계층 만 노출하기 때문에 괜찮습니다.