Nel tentativo di comprendere Domain Driven Design continuo a tornare a una domanda a cui non riesco a dare una risposta definitiva.Quando la logica appartiene all'oggetto/entità aziendale e quando appartiene a un servizio?
Come si determina quale logica appartiene a un'entità di dominio e quale logica appartiene a un servizio di dominio?
Esempio: Abbiamo una classe di ordine per un negozio online. Questa classe è un'entità e una radice aggregata (contiene OrderItem).
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
}
}
penso che la maggior parte delle persone sarebbe d'accordo che CalculateTotalItemWeight appartiene sull'entità. Tuttavia, a un certo punto dobbiamo spedire questo ordine al cliente. Per fare ciò, dobbiamo fare due cose:
1) Determinare la velocità di spedizione necessaria per spedire questo ordine.
2) Stampare un'etichetta di spedizione dopo aver determinato la velocità di spedizione.
Entrambe queste azioni richiedono dipendenze esterne all'entità Ordine, ad esempio un servizio Web esterno per il recupero delle tariffe postali. Come dovremmo realizzare queste due cose? Vedo alcune opzioni:
1) Codificare la logica direttamente nell'entità di dominio, ad esempio CalculateTotalItemWeight. Chiamiamo quindi:
Order.GetPostageRate
Order.PrintLabel
2) Inserire la logica in un servizio che accetta IOrder. Abbiamo poi chiamiamo:
PostageService.GetPostageRate(Order)
PrintService.PrintLabel(Order)
3) Creare una classe per ogni azione che opera su un Ordine, e passiamo un'istanza di tale classe per l'Ordine attraverso Costruttore Injection (questa è una variante dell'opzione 1, ma permette il riutilizzo di le classi RateRetriever e 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)
}
}
Quale di questi metodi si fa a scegliere per questa logica, se del caso? Qual è il ragionamento dietro la tua scelta? Ancora più importante, c'è una serie di linee guida che ti hanno portato alla tua scelta?
un Ordine difficilmente può essere agnostico sui suoi elementi OrderDetail ... era quello che volevi dire? –