将实体添加到DDD中的聚合根的正确方法

时间:2016-03-16 22:05:41

标签: c# domain-driven-design

我有一个名为Order的聚合根,我需要向Product添加Order

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

在谈到这一点时,我想问DDD指南。我面临两个问题:

  1. Product有两个属性,其中包括Product.OrderIDProduct.Order。就DDD而言,我应该在调用 Order.AddProduct之前设置中的哪些属性?

  2. 或者我需要在 Order.AddProduct内设置这两个属性中的任何一个,例如“p.Order = this”;

  3. 请注意,我使用OrderProduct作为示例。我被告知这种关系可能不合适。谢谢。

2 个答案:

答案 0 :(得分:4)

让聚合创建实体。对于客户来说,这是最简单的解决方案,因为“创建”和“添加产品”不是分开的。

property(like -> to_ListTypeGroupAssignmen)
        results(hardcoded & mandatory in every exist object)
             properties(like ListTypeGroup& ListTypeGroupDescription with there values)

请注意,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; } } 的签名可能会因您的需要而异。例如。在某些情况下,您需要提供客户端的ID,而在其他情况下,订单会为产品生成ID。

答案 1 :(得分:1)

我建议使用工厂方法。这是一个例子:

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;
    }
} 

然后,如果你想要你可以让一个订阅者(观察者模式)收听NewItemWasAddedToOrder事件,例如,它可以显示添加到购物车中的项目或类似的东西。

更新:我犯了一个大错,因为我混淆了条款。当我在思考Product时,我正在对Order项进行成像,这是一个不存在的东西,它是在向Order中添加一个新元素时创建的,我认为这是最好的方法。

想象一下,在订单中您保存了ProductId(对产品的引用),另一方面,订购该产品的客户为此支付了20欧元。两个月后,系统管理员更改了同一产品的价格,并且由于您在订单中保存了对该产品的引用,如果您想要检查当天客户支付的金额,您将获得新值。在订单中保存产品,无论何时修改产品,您还要修改订单。

因此,我会在订单中添加一个新商品,其中包含该产品当时具有的具体信息。该项目还应包含对产品的引用,以便了解在给定特定产品的情况下已创建了多少项目。这里的例子是:

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;
    }
}