简体   繁体   中英

Proper way to add an entity to an aggregate root in DDD

I have an aggregate root called Order and I need to add a Product to the Order :

public class Order {
  public void AddProduct(Product p) {
  }
}

I'd like to ask DDD guidelines when it comes to this. I'm facing two questions:

  1. Product has two properties, among others: Product.OrderID and Product.Order . In terms of DDD , which of these properties should I set before calling Order.AddProduct ?

  2. Or is it that I need to set either one of these two properties inside Order.AddProduct , something like " p.Order = this ";

Please note that I'm using Order and Product as examples. I've been told that this relationship may not be appropriate. Thank you.

Let the aggregate create the entity. This is the simplest solution for clients, because "create" and "add product" are not separated.

public class Order 
{
   private readonly List<Product> _products = new List<Product>();

   public Product CreateProduct(string name, Price price) 
   {
      var product = new Product(new ProductId(), name, price);
      _products.Add(product);

      return product;
   }
}

Note that the signature of CreateProduct may vary depending on your needs. Eg in some cases you will want to provide the ID from the client, whereas in other cases the Order generates an ID for the product.

Note: you probably should have aggragate Product and OrderItem or ProductOrderItem entity. OrderItem is entity which will be added to Order. When you edit your product, OrderItems will not be modified.

I would suggest using a factory method. Here an example:

public class Order {
    public Product addProduct(
        ProductId aProductId, 
        String aDescription 
    ) {
        Product product = new Product(
            this.orderId
            aProductId, 
            aDescription
        )

        //Publish event ProductWasAddedToOrder(this.orderId, aProductId) 

        return product;
    }
} 

Then if you want you can have a subscriber (Observer pattern) listening to the NewItemWasAddedToOrder event which, for instance, it can display the item added in a shopping cart or something like that.

Update : I made a big mistake because I confused terms. When I was thinking on Product, I was imaging an Order item, something that does not exist and it is created at the moment of adding a new element to the Order, which I think can be the best way.

Imagine that in the Order you save the ProductId (a reference to the Product), on the other hand the customer who ordered that product paid 20€ for it. Two months later an admin of the system changes the price of the same product, and since you saved in the order a reference to that product if you want to check how much the customer paid that day you will get the new value instead. Saving the Product within the Order, whenever you modify the Product you are also modifying the Order.

Therefore I would add a new Item to the Order with the specific information that the product has at that moment. The item should hold also a reference to the Product just to know how many items have been created given a specific product. Here the example:

public class Order {
    public OrderItem addItem(
        OrderItemId anItemId, 
        ProductId aProductId, 
        Price aPrice, 
        String aDescription 
    ) {
        OrderItem orderItem = new OrderItem(
            anItemId, 
            this.orderId,
            aProductId,
            aDescription, 
            aPrice
        )

        //Publish event NewItemWasAddedToOrder(this.orderId, anItemId) 

        return orderItem;
    }
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM