我正在努力思考如何正确地使用存储库模式。聚合根的核心概念不断出现。当我在web和Stack Overflow上搜索什么是聚合根时,我一直在寻找关于聚合根的讨论,以及指向应该包含基本定义的页面的死链接。
在存储库模式的上下文中,什么是聚合根?
我正在努力思考如何正确地使用存储库模式。聚合根的核心概念不断出现。当我在web和Stack Overflow上搜索什么是聚合根时,我一直在寻找关于聚合根的讨论,以及指向应该包含基本定义的页面的死链接。
在存储库模式的上下文中,什么是聚合根?
当前回答
来自DDD Step By Step(离线):
在一个聚合中有一个聚合根。聚合根为 属性中的所有其他实体和值对象的父实体 聚合。 存储库对聚合根进行操作。
更多信息也可以在这里找到。
其他回答
假设你有一个计算机实体,这个实体也不能没有它的软件实体和硬件实体。这些组成了计算机集合,即域的计算机部分的微型生态系统。
聚合根是聚合(在我们的例子中是Computer)中的母实体,通常的做法是让存储库只与聚合根的实体一起工作,并且这个实体负责初始化其他实体。
将聚合根视为聚合的入口点。
在c#代码中:
public class Computer : IEntity, IAggregateRoot
{
public Hardware Hardware { get; set; }
public Software Software { get; set; }
}
public class Hardware : IEntity { }
public class Software : IValueObject { }
public class Repository<T> : IRepository<T> where T : IAggregateRoot {}
请记住,硬件也可能是一个ValueObject(本身没有标识),仅将其视为一个示例。
如果您采用数据库优先的方法,则聚合根通常是1-多关系中第一边的表。
最常见的例子是Person。每个人都有许多地址、一张或多张工资单、发票、CRM条目等。并非总是如此,但有9/10次都是如此。
我们目前在一个电子商务平台上工作,我们基本上有两个聚合根:
客户 卖家
客户提供联系信息,我们将交易分配给他们,交易获得行项目,等等。
卖家出售产品,有联系人,关于我们的页面,特别优惠等。
这些分别由Customer和Seller存储库负责。
在存储库模式上下文中,聚合根是客户端代码从存储库加载的唯一对象。
存储库封装了对子对象的访问——从调用者的角度来看,它会自动加载它们,要么在加载根对象的同时加载,要么在实际需要它们的时候加载(与惰性加载一样)。
例如,您可能有一个Order对象,它封装了多个LineItem对象上的操作。您的客户端代码永远不会直接加载LineItem对象,只加载包含它们的Order,这将是域的该部分的聚合根。
聚合是通过限制聚合根的访问来保护不变量和强制一致性的地方。不要忘记,聚合应该根据您的项目业务规则和不变量进行设计,而不是数据库关系。不应该注入任何存储库,也不允许进行任何查询。
聚合根是一个简单概念的复杂名称。
一般的想法
设计良好的类图封装了它的内部结构。访问该结构的点称为聚合根。
解决方案的内部结构可能非常复杂,但是这个层次结构的用户将只使用root. dosomethingwherehasbusinessmeaning()。
例子
检查这个简单的类层次结构
你想怎样驾驶你的车?选择更好的API
选项A(它只是以某种方式工作):
car.ride();
选项B(用户可以访问类内部内容):
if(car.getTires().getUsageLevel()< Car.ACCEPTABLE_TIRE_USAGE)
for (Wheel w: car:getWheels()){
w.spin();
}
}
如果你认为选择A更好,那么恭喜你。你得到了根集合背后的主要原因。
聚合根封装多个类。您只能通过主对象操作整个层次结构。