Định dạng ngắn của câu hỏi
Có phải trong các thực tiễn tốt nhất của DDD và OOP để tiêm dịch vụ vào các cuộc gọi phương thức thực thể không?
Ví dụ định dạng dài
Giả sử chúng ta có trường hợp Order-LineItems cổ điển trong DDD, trong đó chúng ta có một Thực thể Miền được gọi là Đơn hàng, cũng hoạt động như Root tổng hợp, và Thực thể đó không chỉ bao gồm các Đối tượng Giá trị, mà còn là một tập hợp các Mục hàng Các thực thể.
Giả sử chúng ta muốn cú pháp trôi chảy trong ứng dụng của mình, để chúng ta có thể làm một cái gì đó như thế này (lưu ý cú pháp trong dòng 2, nơi chúng ta gọi getLineItems
phương thức):
$order = $orderService->getOrderByID($orderID);
foreach($order->getLineItems($orderService) as $lineItem) {
...
}
Chúng tôi không muốn đưa bất kỳ loại LineItemRep repository nào vào OrderEntity, vì đó là vi phạm một số nguyên tắc mà tôi có thể nghĩ ra. Nhưng, sự trôi chảy của cú pháp là điều mà chúng tôi thực sự muốn, bởi vì nó dễ đọc và duy trì, cũng như kiểm tra.
Hãy xem xét các đoạn mã sau, lưu ý phương thức getLineItems
trong 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;
}
}
Đó có phải là cách được chấp nhận để thực hiện cú pháp trôi chảy trong Thực thể mà không vi phạm các nguyên tắc cốt lõi của DDD và OOP? Đối với tôi có vẻ ổn, vì chúng tôi chỉ phơi bày lớp dịch vụ, không phải lớp cơ sở hạ tầng (được lồng trong dịch vụ)