繁体   English   中英

避免在聚合中引用实体的最佳方法是什么?

[英]What is the best way to avoid referencing an entity inside an aggregate?

我是 DDD 的新手。 我刚刚通过 DDD 架构启动了一个项目。 在域设计中,我遇到了一个问题。 假设我有一个客户应该向我发送他/她的订单清单,例如:

customer1:{Onion,Apple,orange,wireless Mouse,PC,fish,egg}

每个项目都可以委托给不同的商店:

Grocery Store:{onion,apple,orange,fish,egg}
Digital Store:{wireless mouse,PC}
butchery:{fish,egg}

每个订单只有一个名字。 要验证客户的订单列表,我应该将验证委托给客户作为“AggregateRoot”,并将订单列表视为“列表”:

public class Customer : AggregateRoot<long>
{
    public long Id { get;private set; }
    public string CustomerName { get;private set; }

    private List<Order> _orders = new List<Order>();
    public IReadOnlyCollection<Order> Orders => _orders.AsReadOnly();

    public Customer(long id, string customerName)
    {
        Id = id;
        CustomerName = customerName;
    }

    public void AssignOrders(List<Order> orders)
    {
        //check some validation on orders before assignments
        this._orders=orders;
    }
}

public class Order : Entity<long>
{
    public long Id { get;private set; }
    public string Name { get;private set; }

    public Order(long id,string name)
    {
        //check some validation for single order before creation
        this.Id=id;
        this.Name=name; 
    }
}

但是当我想将“订单”分配给“商店”时出现了我的设计问题:基于 DDD 规则“聚合根不应包含对另一个聚合根中的实体的引用”

public class Store:AggregateRoot<long>
{
    public long Id { get;private set; }
    public string StoreName { get;private set; }
    private List<Order> _orders = new List<Order>();
    public IReadOnlyCollection<Order> Orders => _orders.AsReadOnly();

    public Store(string storeName, long id)
    {
        StoreName = storeName;
        Id = id;
    }

    public void AssignOrders(List<Order> orders)
    {
        //check some validation on orders before assignments
        this._orders = orders;
    }
}

在我的设计中,“商店”是一个聚合根,需要有订单列表。 旁边有分配给多个商店的订单。 现在你的建议是什么:

  1. 我是否应该将“订单”作为“客户”中的实体保留,并将“商店”列表分配给每个“订单”。
  2. 我应该将“订单”保留为带有订单列表和“customerId”的聚合根,但是如何完全验证列表?
  3. 我是否应该将“客户”中的“订单”更改为价值对象列表,然后将它们复制为订单(难以维护,因为还有其他聚合根需要“订单”列表,而商店就是其中之一)

如果可以的话,我建议您与您的领域专家交谈,以澄清业务是如何完成的。 然后,您可以找到 model 所需的不同实体。

看起来您可能在这里有 2 个子域(“世界视图”): CustomerStore两者都有一个Order的概念,但这些订单是不同的。

可能这个 model 可以使用:

CustomerOrder - 一组客户想要购买的商品。 它有许多包含Product ID / Quanity / VolumeCustomer Order Line对象。 当您创建此CustomerOrder object 时,您可以对其进行验证。 您还可以通过一些简单的检查来验证每个Customer Order Line ,例如,至少数量或数量 > 0 等。

StoreOrder是商店收到的订单。 它还包含一个Store Order Line对象列表。 这与CustomerOrder不同。 它将包含不同的项目,可以汇总,可以包含其他信息等。

与您的领域专家交谈以验证 model。 如果您手边没有任何领域专家,请实施一些可以让您继续前进并在需要时对其进行改进的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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