Domain driven design 我可以调用聚合根中实体的操作吗?

Domain driven design 我可以调用聚合根中实体的操作吗?,domain-driven-design,Domain Driven Design,根据标题,我有以下课程: public class Company : AggregateRoot { public AddressBook AddressBook { get; set; } } public class AddressBook { public List<Address> Addresses { get; set; } public Address GetPrimaryAddress() { return Address

根据标题,我有以下课程:

public class Company : AggregateRoot {
    public AddressBook AddressBook { get; set; }
}

public class AddressBook {
    public List<Address> Addresses { get; set; }

    public Address GetPrimaryAddress() {
        return Addresses.FirstOrDefault();
    }
}
或者我应该在
Company
上公开一个
GetPrimaryAddress()
方法,该方法反过来调用
AddressBook
方法吗

我知道我不应该在AggregateRoot中引用实体,但我不确定调用操作的规则是什么

更新 值得一提的是,下面是我实际模型的示意图(点击查看全尺寸)<代码>联系人列表包含如何管理所有类型的联系人(个人/业务地点)的规则,例如删除主要联系人时会发生什么。它还围绕RavenDB如何存储嵌套实体的一些注意事项(本质上我们需要提供自己的Id策略,因此需要LastContactId属性)

根据聚合模式:

对内部成员的瞬态引用只能传递给单个操作中使用

含义-公司可以将对其地址对象的引用传递给聚合外部的其他对象,但地址不能是聚合外部任何其他对象的成员

例如,对象用户可以向公司请求对地址的引用,但用户不能将地址作为其成员之一

这为什么如此重要

因为根目录控制访问,所以它不能被内部的更改所蒙蔽

如果一个对象用户将Address作为其成员之一,它可能会在没有公司的情况下将其从数据库中拉出,因此,公司将被其内部的更改所蒙蔽

请看我写的一篇文章,其中我演示了为什么这一原则如此重要。

根据聚合模式:

对内部成员的瞬态引用只能传递给单个操作中使用

含义-公司可以将对其地址对象的引用传递给聚合外部的其他对象,但地址不能是聚合外部任何其他对象的成员

例如,对象用户可以向公司请求对地址的引用,但用户不能将地址作为其成员之一

这为什么如此重要

因为根目录控制访问,所以它不能被内部的更改所蒙蔽

如果一个对象用户将Address作为其成员之一,它可能会在没有公司的情况下将其从数据库中拉出,因此,公司将被其内部的更改所蒙蔽


请看我写的一篇文章,我在其中演示了这一原则为何如此重要。

好问题,这是我在DDD中一直发现很难做到的事情之一-您是否总是通过实体的聚合根访问实体,并且在某个点上可能违反了(AggregateRoot.EntityX.EntityY.DoStuff())?是否会使聚合根短路?您是否在聚合根级别为每个要访问的子实体添加了一个直接访问器,从而混淆了聚合根

解决这个问题的一种方法是:让每个物体只和它的近邻或附近的邻居说话,而不是和远处的陌生人说话。使用多个对象,每个对象都知道从聚合根到要访问的最终实体的一小部分路径

  • 第一个对象只知道聚合根

  • 它将AggregateRoot.SubEntity1注入第二个对象

  • 第二个对象依次将SubEntity1.SubEntity2注入第三个对象

  • 等等

足够有趣的是,这揭示了一件事,那就是一些域实体的(ir)相关性。在地址示例中,问问自己,如果每个想要访问公司主地址的对象都被注入一个地址簿,这是否合适。如果它看起来太复杂,也许你首先不应该有一个通讯录。也许这不是一个很强的概念,毕竟它应该成为无处不在的语言的一部分


或者,您可能会发现AddressBook正是您的客户机对象所使用的正确对象,并且该客户机对象试图在同时操纵公司和地址时做太多事情。

好问题,这是我一直发现在DDD中很难做到的事情之一-您是否总是通过实体的聚合根访问实体,并且可能在某个时候违反了(AggregateRoot.EntityX.EntityY.DoStuff())?是否会使聚合根短路?您是否在聚合根级别为每个要访问的子实体添加了一个直接访问器,从而混淆了聚合根

解决这个问题的一种方法是:让每个物体只和它的近邻或附近的邻居说话,而不是和远处的陌生人说话。使用多个对象,每个对象都知道从聚合根到要访问的最终实体的一小部分路径

  • 第一个对象只知道聚合根

  • 它将AggregateRoot.SubEntity1注入第二个对象

  • 第二个对象依次将SubEntity1.SubEntity2注入第三个对象

  • 等等

足够有趣的是,这揭示了一件事,那就是一些域实体的(ir)相关性。在地址示例中,问问自己,如果每个想要访问公司主地址的对象都被注入一个地址簿,这是否合适。如果它看起来太复杂,也许你首先不应该有一个通讯录。也许这不是一个很强的概念,毕竟它应该成为无处不在的语言的一部分


或者,您可能会发现AddressBook正是您的客户机对象所使用的正确对象,并且该客户机对象试图在同时操纵公司和地址时做太多事情。

首先,这取决于上下文,我假设公司确实是该spe的AR
company.AddressBook.GetPrimaryAddress();