【问题标题】:Does Aggregate root class holds only publicly exposed methods聚合根类是否仅包含公开公开的方法
【发布时间】:2020-01-16 18:51:47
【问题描述】:
我正在尝试理解 AggregateRoots 的概念。假设我有一个课程Customer、Holiday、Address、Document。
如果我理解正确,聚合根应该是一个负责操作某些业务规则的类。在这种情况下,我认识了一个 Customer 类,它应该负责为给定的客户分配假期记录以及其他信息(地址和文档)。
我的问题是:
- 我应该为我的聚合根 (CustomerAggregate) 而不是客户遵循一些文件名约定吗?
- 我是否应该将所有其他类(
Holiday、Address、Document)设为对外界不可见(聚合根是进一步使用这些类的唯一入口点,如果是的话,什么是最好的?练习这个?
- 我是否应该将我的聚合根构建为域服务类,其中包含所有可能的公共入口点(客户执行此操作,客户执行此操作)以及该类的所有属性?
【问题讨论】:
标签:
java
.net
domain-driven-design
microservices
【解决方案1】:
在 domain-driven-design 中,聚合的通常起点是 Eric Evans 的书。
AGGREGATE 是一起变化的领域模型实体的图。许多聚合中只有一个实体,但通常可以有多个。
AGGREGATE ROOT 是聚合中允许应用程序与之交互的单个实体——根实体充当整个聚合的接口。这样可以更轻松地确保保持不变式 - 所有更改都必须通过一个阻塞点。
我应该为我的聚合根 (CustomerAggregate) 而不是客户遵循一些文件名约定吗?
这并不重要,但在大多数示例中,根对象使用域模型中实体的命名约定,而不是拥有自己的特殊约定。所以Customer 将是您期望看到的。
我应该让所有其他类对外界不可见
不一定 - 重要的是要确保外部世界始终通过阻塞点。使用纪律和代码审查来强制执行这一点很好。如果您使用的是存储库模式,则可以将这些接口限制为仅公开根对象。在java中,您可以将聚合的所有实体放在一个包中,并确保只有根对象具有公共访问级别修饰符。
在许多情况下,防止模型被意外误用就足够了。
我是否应该以域服务类的方式构建我的聚合根,其中包含所有可能的公共入口点(客户执行此操作,客户执行此操作)以及该类的所有属性?
这个问题很难回答,因为domain service 被用作domain-driven-design 中的模式名称——实体和域服务是不同的东西,所以制作一个aggregate root(这是一个实体,见上文)就像domain service 是方向错误的一步。
域实体通常包含一个接口,该接口描述它所期望的消息,以及它用来跟踪其自身状态的封装数据结构。