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
OrderHeader
s perOrderLine
is that intentional?Order
and another publicOrderItem
class since anOrderItem
class cannot, and should never, be used in isolation. I'm all for ease of testing, though :) --- An aggregate root in DDD encapsulates the relevant invariants so having the item coupled to the order seems a reasonable thing to do. YMMVOrder
in this case is explicitly coupled to itsLine
. Need to use a different sort ofLine
? Of course you can do it, but the structure will fight you. Fighting with the structure is not conducive to good programming. As for the logical nesting would it not make more sense to using the scoping? ie:Shopping.Order
andShopping.Item
whereShopping
is a package/namespace. That would be both more informative (its a shopping order vs a fulfilment order vs. a stocking order), and provides a cleaner interface.Shopping.Item
that could be re-used in aShopping.Order
and in aShopping.FulfilmentOrder
then that is a design choice and may even be an internal "base" class to nested classes. Perhaps a fulfilment order is simply a type of order and can be handled using a normal order with a type. I haven't ever come across a fulfilment order in my career so my understanding may be lacking. In any event, the design should always aid in testing no matter the implementation details as alluded to by@ candied_orange.