Pregunta

I had asked a question here, and someone had recommended that OrderLine be a Nested class within Order Header. Is that a standard practice in Domain Driven Design, or more one of many debated methods of conducting DD, with nested class? Just want to validate if this is industry wide practice recommended from DDD Author EricEvans.

https://stackoverflow.com/questions/57549607/domain-driven-design-order-and-order-line-classes

We know in a Database Model, Order and Orderline are generally two separate tables.

Database Models from Scaffold:

public class OrderHeader  
{
    public int OrderHeaderId { get; set; }
    public int CustomerId { get; set; }
    public int OrderLineNumber { get; set;}

    public virtual ICollection<OrderLine> OrderLine{ get; set; }
}


public class OrderLine
{
    public int OrderLineNumber { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; 

    public virtual ICollection<OrderHeader> OrderHeader { get; set; }
}

Recommended Example:

public class Order
{
    public int OrderId { get; }
    public int CustomerId { get; }

    private readonly List<OrderLine> _orderLine = new List<OrderLine>();

    public Order(int orderid, int customerId)
    {
        OrderId = orderId;
        CustomerId = customerId;
    }

    public IEnumerable<OrderLine> GetItems() => _orderLine .AsReadOnly();

    public void AddOrderItem(int productId, string description, intcount, decimal unitPrice)
    {
        _orderLine.Add(new Item(productId, description, count, unitPrice));
    }

    public class OrderItem
    {
        // get-only properties
        internal Item(intproductId, string description, int count, decimal unitPrice)
        {
        }
    }
}

https://stackoverflow.com/questions/4329322/ddd-aggregate-root-example-order-and-orderline

¿Fue útil?

Solución

From an RDBMS point of view, Order and OrderLine are two tables without a doubt. The decision on whether to nest OrderLine within Order is dependent on answers to three questions:

  • Do the business rules of Order include maintaining data spread across Order and OrderLine? For example, the order amount is always equal to the sum(qty * price) of all OrderLines. If so, then OrderLine is within the invariant boundary of Order, and Order aggregate should take responsibility for persisting and loading OrderLine items. That's the only way to make sure that the invariant rules are satisfied all the time.
  • The second aspect is an exception to the earlier rule. Sometimes, the child entity (OrderLine in your example) can be in huge numbers that it doesn't make sense to enforce invariant rules in real-time. For instance, Followers of a User, though very much part of the User aggregate, would need to be modeled separately as an aggregate of its own. Because as your application scales, loading and persisting all followers of a user is no longer viable or sensible. Unless the number of order items in your order exceeds, say, 100 pieces, it should be ok to keep OrderLine within Order. Still, if you observe performance issues on large orders, this may be the way to go.
  • The third aspect has to do with practical usage in your application. If you plan to access the child object on its own, without requiring the parent object to be present, then it may make sense to treat the child object as an aggregate of its own. For example, Tasks in a Project may have a considerable amount of functionality of their own, and may not need always to be referenced in the context of a project. There would be a ProjectId connecting the task to the project, but you wouldn't always traverse the project.tasks path for operating on tasks. In such cases, you would treat the child object as a new aggregate.

DDD Nomenclature-wise, the nested OrderLine would be called an Entity and would be part of the Order Aggregate.

Note that your code structure in the domain layer has nothing to do with persistence. For example, you may switch to a Document DB like Mongo tomorrow and store both Order and OrderLine as a combined structure. But this wouldn't change how you place the classes in the domain layer.

Licenciado bajo: CC-BY-SA con atribución
scroll top