Khi cố gắng hiểu Thiết kế Điều khiển Tên miền, tôi tiếp tục quay lại câu hỏi mà tôi dường như không thể trả lời dứt khoát.Khi nào thì logic thuộc về đối tượng/đối tượng kinh doanh và khi nào thuộc về một dịch vụ?
Làm cách nào để bạn xác định logic nào thuộc về thực thể Tên miền và logic nào thuộc về Dịch vụ miền?
Ví dụ: Chúng tôi có một lớp Đặt hàng cho một cửa hàng trực tuyến. Lớp này là một thực thể và một gốc tổng hợp (nó chứa OrderItems).
Public Class Order:IOrder
{
Private List<IOrderItem> OrderItems
Public Order(List<IOrderItem>)
{
OrderItems = List<IOrderItem>
}
Public Decimal CalculateTotalItemWeight()
//This logic seems to belong in the entity.
{
Decimal TotalWeight = 0
foreach(IOrderItem OrderItem in OrderItems)
{
TotalWeight += OrderItem.Weight
}
return TotalWeight
}
}
Tôi nghĩ hầu hết mọi người đều đồng ý rằng CalculateTotalItemWeight thuộc về pháp nhân. Tuy nhiên, tại một số thời điểm chúng tôi phải giao hàng cho khách hàng. Để thực hiện điều này, chúng tôi cần thực hiện hai điều:
1) Xác định tỷ lệ bưu chính cần thiết để giao đơn đặt hàng này.
2) In nhãn vận chuyển sau khi xác định cước phí bưu chính.
Cả hai hành động này sẽ yêu cầu các phụ thuộc nằm ngoài thực thể Đơn đặt hàng, chẳng hạn như dịch vụ web bên ngoài để truy xuất tỷ lệ bưu chính. Chúng ta nên hoàn thành hai điều này như thế nào? Tôi thấy một vài tùy chọn:
1) Mã logic trực tiếp trong thực thể tên miền, như CalculateTotalItemWeight. Sau đó chúng tôi gọi:
Order.GetPostageRate
Order.PrintLabel
2) Đặt logic trong dịch vụ chấp nhận IOrder. Sau đó chúng tôi gọi:
PostageService.GetPostageRate(Order)
PrintService.PrintLabel(Order)
3) Tạo một lớp cho mỗi hành động mà hoạt động trên một thứ tự, và vượt qua một thể hiện của lớp đó để Huân qua Constructor Injection (đây là một biến thể của phương án 1 nhưng cho phép tái sử dụng các lớp RateRetriever và LabelPrinter):
Public Class Order:IOrder
{
Private List<IOrderItem> OrderItems
Private RateRetriever _Retriever
Private LabelPrinter _Printer
Public Order(List<IOrderItem>, RateRetriever Retriever, LabelPrinter Printer)
{
OrderItems = List<IOrderItem>
_Retriever = Retriever
_Printer = Printer
}
Public Decimal GetPostageRate
{
_Retriever.GetPostageRate(this)
}
Public void PrintLabel
{
_Printer.PrintLabel(this)
}
}
Bạn chọn phương pháp nào trong logic này nếu có? Lý do đằng sau sự lựa chọn của bạn là gì? Quan trọng nhất, có một bộ hướng dẫn nào dẫn bạn đến lựa chọn của bạn không?
Lệnh khó có thể thuyết bất khả tri về các mục OrderDetail của mình ... Đó có phải là những gì bạn có nghĩa là? –