When does logic belong in the Business Object/Entity, and when does it belong in a Service?
        Posted  
        
            by 
                Casey
            
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Casey
        
        
        
        Published on 2011-01-29T23:23:29Z
        Indexed on 
            2011/01/29
            23:25 UTC
        
        
        Read the original article
        Hit count: 239
        
In trying to understand Domain Driven Design I keep returning to a question that I can't seem to definitively answer.
How do you determine what logic belongs to a Domain entity, and what logic belongs to a Domain Service?
Example: We have an Order class for an online store. This class is an entity and an aggregate root (it contains 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
    }
}
I think most people would agree that CalculateTotalItemWeight belongs on the entity. However, at some point we have to ship this order to the customer. To accomplish this we need to do two things:
1) Determine the postage rate necessary to ship this order.
2) Print a shipping label after determining the postage rate.
Both of these actions will require dependencies that are outside the Order entity, such as an external webservice to retrieve postage rates. How should we accomplish these two things? I see a few options:
1) Code the logic directly in the domain entity, like CalculateTotalItemWeight. We then call:
Order.GetPostageRate
Order.PrintLabel
2) Put the logic in a service that accepts IOrder. We then call:
PostageService.GetPostageRate(Order)
PrintService.PrintLabel(Order)
3) Create a class for each action that operates on an Order, and pass an instance of that class to the Order through Constructor Injection (this is a variation of option 1 but allows reuse of the RateRetriever and LabelPrinter classes):
 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)
    }
}
Which one of these methods do you choose for this logic, if any? What is the reasoning behind your choice? Most importantly, is there a set of guidelines that led you to your choice?
© Stack Overflow or respective owner