聚合根取决于用例,这是否意味着我们最终可能会拥有大量的存储库?

时间:2011-02-01 13:09:58

标签: domain-driven-design

我听说过根据用例而来的聚合根。但这在编码环境中意味着什么?

你有一个服务类,其中offcourse持有将在存储库中完成某些事情的方法(用例)。太棒了,所以你使用一个等于聚合根的存储库来执行你的查询。

现在您需要执行一些其他类型的操作,这些操作使用与第一个服务类完全不同的用例,但使用相同的实体。

这里的表示:

实体:客户,订单,LineOrder

服务1:添加新客户,删除部分客户,检索客户订单

此处聚合根似乎是Customer,因为您需要此存储库来执行用例。

服务2:从实际订单中检索客户

此处聚合根似乎是Order,因为您需要此存储库来执行此用例。

如果我错了,请纠正我。现在这意味着你有2个聚合根。

现在我的问题是,因为聚合根取决于用例,这是否意味着如果最终有大量用例,我们最终可能会得到很多存储库?

上面的例子可能不是最好的例子......所以我们假设我们有一个Journal,它包含JournalEntries,每个条目都包含任务,问题和注释。 (这是告诉系统对项目做了什么)

这是否意味着我最终将获得2个存储库? (Journal,JournalEntry) 在我需要从日记帐分录中添加新任务,问题和备注的用例中? (可以看作是服务)

或者最终可能会有4个存储库。 (期刊,任务,问题,笔记) 在我需要访问直接任务,问题和注释的用例中? (可以看作是另一项服务)

但这意味着如果我需要这两个服务(实际上持有用例),我实际上需要5个存储库才能在这两个服务器中执行用例?

感谢。

3 个答案:

答案 0 :(得分:2)

嗨,我看到了你的帖子,并认为我可能会给你我的意见。首先,我必须说我已经在项目中做了三年的DDD,所以我不是专家。但我目前正在一个项目中担任建筑师,DDD的教练开发人员,我必须说它不是在公园散步......我不知道有多少次我重构了模型和实体关系。

但我的经验是你最终得到了一些存储库(超过少数但不多)。 My Aggregates通常包含几个类,而Aggregate对象图不是那么深(如果你知道我的意思)。

但我试着具体:

1)聚合根源由您的需求定义。我的意思是如果你觉得你经常需要通过Journal来处理那个Tasks对象,那么也许这就是它作为聚合根升级的标志。

2)但是一切都不能是聚合根,所以尝试封装紧密相关的对象。 Notes似乎是由根对象拥有的候选者。您可能始终将Notes与根关联或丢失其上下文。笔记本身不能生存。

3)请记住,聚合体用于将大型复杂域分割成较小的“岛屿”,以照顾他们的居民。重要的是不要使你的领域比它更复杂。

4)在进入项目实施阶段之前,您不知道模型的外观。如果你意识到某些存储库没有那么多使用,它们可能是合并到其他根对象的候选者(如果他们有这种关系)。您可以在没有上下文的情况下分解通过根对象使用过的对象。我的意思是,例如,如果Journal是聚合根并包含Notes和Tasks。一段时间后,你的模型会增长,也许是任务 有行动和行动历史和用户和规则和许可的协助。现在我只是在规则/动作/用户权限功能中抛出一堆常见对象。也许这导致用户从另一个角度处理任务,“查看此用户执行的所有任务”等。任务更多地涉及某种状态/工作流引擎,因此作为聚合根本身的候选者。

奥基。不是最好的例子,但它可能会给你一个想法。根对象可以包含子节点,其中一些子节点也可以是根对象,因为我们在另一个上下文(比期刊)中需要它。 但每当你用新车型启动时,我都会把自己的头撞在墙上。只需顺其自然,让模型通过其客户/子服务员自我发展。您可以通过其用途细化模型。服务(应用程序服务而非域服务)当然扩展为响应UI和用例(通常是一对一)的方法。

我希望我能在某种程度上帮助你......或者不是:D

答案 1 :(得分:1)

是的,您最有可能最终得到5个存储库(Journal,JournalEntry,Task,Problems,Notes)。然后,您的服务将使用这些存储库为每种类型的实体执行CRUD。

对于DDD新手的开发人员而言,“哇这么多存储库”的反应并不少见。

但是,假设您的模型和数据库架构相当均匀匹配(通常就是这种情况),您的存储库通常很轻。如果您使用ORM(如nHibernate)或工具(如代码生成器),则可以更轻松地创建存储库。

答案 2 :(得分:0)

首先,您需要定义什么是聚合。我不知道用例聚合。 我知道跟随...的总量 聚合是几个实体的联合。其中一个实体是聚合根,其余实体(或值类型)仅在选定的聚合根上下文中有意义。
例如,如果您不需要对OrderLine实体执行任何独立操作,则可以将Order和OrderLine定义为聚合。这意味着OrderLine仅在Order上下文中有意义。 为什么要定义聚合?需要减少对象之间的引用。这将简化您的域模型。
当然,如果OrderLine是Order聚合的一部分,您不需要拥有OrderLineRepository。 这是一个link,其中包含更多信息。你可以阅读Eric Evans DDD一书。他很好地解释了聚合。