众所周知,聚合由工厂创建,在对象生命周期的活动阶段表示内存中的底层实体(见图1.3,回顾下一个Account的生命周期)。但是,当您不再需要它时,您还需要一种方法来持久化聚合。你不能把它扔掉,因为你可能需要以后再去取它。
仓储为您提供了这样一个接口,可以将聚合体以持久的形式存放,这样您就可以在需要时将其返回到内存中的实体表示中。通常,仓储都具有基于持久性存储的实现,例如关系数据库管理系统(RDBMS),尽管契约并没有强制要这么执行(在许多小型应用程序中,您可以拥有一个内存存储库。但事实并非如此)。还请注意,聚合的持久模型可能与内存中的聚合表示完全不同,并且主要是由底层存储数据模型驱动的。仓储的职责(见下面清单1.3)是提供从持久性存储中操作实体的接口,而不需要暴露底层关系型(因为我们这里是以关系型数据库谈的,其实应该是任何底层存储支持的模型,比如redis所支持的键值对,还有Neo4j的图形数据库)数据模型。
仓储的接口不知道底层持久性存储的本质。它可以是关系数据库,也可以是NoSQL数据库---只有接口的实现才知道到底是那种。因此,一个聚合为实体在内存中的表现提供了什么,仓储也就是为持久性存储做的相同的事。一个聚合隐藏了对象的内存表现的 底层细节,而一个仓储则抽象了对象的持久化表现的 底层细节。清单1.3展示了一个 AccountRepository从底层存储中操作Account;而该清单没有显示存储库的任何具体实现。但是用户仍然通过聚合来与仓储交互。看看下面的这个列表,了解一个聚合如何为一个实体的整个生命周期提供一个窗口:
你向工厂提供了大量的参数,然后得到一个聚合
通过服务(清单1.2中的 AccountService )实现的所有行为,你都可以使用聚合作为契约(例如清单1.2中的Account)
您使用聚合来持久化仓储中的实体(看清单1.3)
到目前为止,您已经看到了使用限界上下文在模型中实现模块化,您需要实现的三种最重要的领域元素类型(实体、值对象和服务),以及用于操作它们的三种模式(工厂,聚合和仓储)。正如您现在必须认识到的,这三种元素参与了领域交互(如银行系统中的借方、贷方等),它们的生命周期由三种模式控制。在域驱动设计中,最后要讨论的是将所有这些都绑定在一起的一个方面。它被称为模型的词汇表,在下一节中,您将了解为什么它是重要的。