问题的简短格式
在DDD和OOP的最佳实践中,是否可以在实体方法调用上注入服务?
长格式示例
假设我们在DDD中有一个经典的Order-LineItems案例,其中有一个称为Order的域实体,它也充当聚合根,并且该实体不仅由其Value Objects组成,而且还包含Line Item的集合实体。
假设我们希望在应用程序中使用流利的语法,以便我们可以做类似的事情(请注意第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和OOP核心原则的公认方法吗?在我看来,这很好,因为我们仅公开服务层,而不公开基础结构层(嵌套在服务中)