DDD、聚合和实体

DDD, Aggregates and Entities

我有以下域对象结构

Invoice
 - List<Items>
      - Service

发票有一个项目列表,每个项目都有一项服务。

数据库结构如下

Invoices Table
Items Table (fk to invoice, fk to service)
Services Table

如果我没理解错的话,在这种情况下,Invoice 是聚合的,items 是实体,service 是 Item 的值对象?

如果我需要向数据库添加新服务会发生什么。我是否应该创建一个新的 Service class,然后它将针对该场景聚合,并拥有自己的存储库?

服务可以独立存在吗? - 看起来他们可以根据你上面的内容。

如果您需要向数据库添加新服务(我假设服务是独立的),那么您需要创建一个服务聚合根。还将有一个服务存储库等用于添加它。

聚合根和存储库始终是一对一的。他们的关键是了解您域中的聚合根是什么。正确定义这些后,存储库就是自定义的。

请注意,如果您需要在上面的示例中向发票添加新项目之类的内容,则必须通过发票存储库来执行此操作。原因很简单,因为Item是实体,不是聚合根。

Invoice
 - List<Items>
      - Service

首先要注意的是 - 这是对 结构 的描述。 DDD 中聚合的动机不是结构,而是 行为 。聚合的作用是确保对结构的修改符合业务规则。

If i understood correctly, Invoice is aggregate, items are entities and service is value object for Item in this scenario?

很接近,但术语比那更含糊(抱歉)。如果此结构表示聚合边界内的状态,则 Invoice 将是充当 aggregate root 的实体,聚合本身通常称为 Invoice aggregate.

项目和服务可能是值类型,也可能是实体。您需要更多信息才能确定。从名字(应该取自无处不在的语言)猜测,它们很可能都是实体。 ServiceNameServiceId 更可能是值类型。

重要的一点:如果这些是实体,则它们的生命周期从属于 Invoice 的生命周期。换句话说,"cascade delete" 的发票会带走物品和服务。

What happens if i need to add new services to database. Should i create a new Service class, which will then be aggregate for that scenario, and have it's own repository?

稍微倒退:持久性组件支持域模型,而不是相反。

如果服务是一个实体,并且该实体的生命周期独立于任何一张发票(例如,如果两张不同的发票可以引用 "same" 服务),那么服务实体应该与发票处于不同的聚合中,并且发票的状态包含对服务的引用,而不是服务本身。

如果这是正确的模型,那么服务聚合将拥有自己的存储库。