質問の短い形式
エンティティメソッドの呼び出しにサービスを注入することは、DDDおよびOOPのベストプラクティスの範囲内ですか?
長い形式の例
DDDに従来のOrder-LineItemsケースがあるとします。ここでは、Orderと呼ばれるドメインエンティティがあり、これは集約ルートとしても機能し、そのエンティティは値オブジェクトだけでなく、ラインアイテムのコレクションからも構成されます。エンティティ。
アプリケーションで流暢な構文を使用して、次のようなことができると仮定します(getLineItems
メソッドを呼び出す2行目の構文に注目してください)。
$order = $orderService->getOrderByID($orderID);
foreach($order->getLineItems($orderService) as $lineItem) {
...
}
OrderEntityにLineItemRepositoryを挿入したくないのは、それが考えられるいくつかの原則に違反しているためです。しかし、構文の流暢さは私たちが本当に望んでいるものです。それは、テストだけでなく、読みやすく、保守しやすいからです。
のメソッド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のコア原則に違反することなく、エンティティに流暢な構文を実装する方法として受け入れられていますか?インフラストラクチャレイヤー(サービス内にネストされているレイヤー)ではなく、サービスレイヤーのみを公開しているので、私には問題ないようです。