DDD-聚合根的存储库是否处理保存的聚合?


27

我正在对现有应用程序的未开发模块使用类似DDD的方法;由于架构原因,它不是100%DDD,但我正在尝试使用一些DDD概念。我有一个界上下文(我认为这是适当的期限-我仍然在学习DDD)由两个实体:ConversationMessage。对话是根源,因为没有对话就不存在消息,并且系统中的所有消息都是对话的一部分。

我有一个ConversationRepository类(尽管它实际上更像是一个网关,但我使用术语“存储库”)可以在数据库中找到会话。当找到会话时,它还会(通过工厂)为该会话创建消息列表(作为属性公开)。这似乎是正确的处理方式,因为似乎不需要完整的MessageRepository类,因为只有在检索到对话时才存在该类。

但是,在保存消息时,由于它是Message的聚合根,这是ConversationRepository的责任吗?我的意思是,我是否应该在ConversationRepository上有一个名为AddMessageMessage 的方法,该方法将Message作为参数并将其保存到数据库中?还是应该有一个单独的存储库来查找/保存消息?逻辑上似乎是每个实体一个存储库,但是我也听说过“每个上下文一个存储库”。

Answers:


25

蓝皮书是绝对值得一读,如果你想获得DDD方法最好了。DDD模式并非易事,了解每种模式的本质将帮助您思考何时使用哪种模式,如何将应用程序划分为多个层,如何定义聚合等等。

您提到的2个实体组不是有界上下文-可能是聚合。每个聚合都有一个聚合根,这是一个实体,它充当所有其他对象的聚合的单个入口点。因此,一个实体与另一个不是聚合根的聚合中的另一个实体之间没有直接关系。

需要存储库来获取通过遍历其他对象不容易获得的实体。存储库通常包含聚合根,但是也可以有常规实体的存储库。

在您的示例中,会话似乎是聚合根。会话可能是您应用程序的起点,或者您可能想用详细的条件查询它们,因此无法通过简单遍历其他对象来令人满意地访问它们。在这种情况下,您可以为他们创建一个存储库,该存储库将使客户代码具有一组可直接从中查询,添加或删除的内存中会话的幻觉。另一方面,通过遍历会话很容易获得消息,并且您可能不希望根据详细的条件来获取消息,而是一次获取所有会话的消息,因此它们可能不需要存储库。

ConversationRepository将在持久化消息中发挥作用,但不会像您提到的那样直接发挥作用。因此,在ConversationRepository上没有AddMessage()(该方法而是属于Conversation本身),而是每次Repository保留一个Conversation时,最好同时保留其Messages(如果您使用ORM框架,则可以透明地保留)例如(N)Hibernate,如果选择的话,使用临时SQL,等等。


1
如果聚合根(例如“对话”)中有许多不同的实体类型,例如“消息”,“ Thingies”和“ Wingies”,那么当您保存对话(例如ConversationRepo.save(conversation))时,您如何知道其中需要哪些实体被保存?在上面的张贴者示例中,仅需要保存消息实体。您是否遍历了聚合根中的所有可能的集合以查找没有id的实体?
克里斯·理查兹

3

您可以创建ConversationService并将IConversationRepositoryIMessageRepository注入其构造函数中。使用存储库进行简单的CRUD操作,并使用服务进行其他所有操作(缓存,保存逻辑等)


1
不保存逻辑CRUD吗?
蒂莫西·格罗特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.