项目中的
repositories
层需要创建 aggregate root
的实例,以便它可以重用其存储的数据,并返回 aggregate toot
的实例,是吗?
如果是这样...这意味着
aggregate root
客户端(可能是其他在服务层工作的开发人员)可以使用存储库层使用的相同功能来创建他们自己的aggregate root
版本(打破封装的想法) ...我知道他们不应该,但是如果存在这样的功能,聚合根边界规则如何不会被破坏,并且有什么方法可以强制执行客户端行为。
我创建了一个
aggregate root
来封装行为和其边界内包含的数据,这个 aggregate root
为代码客户端提供了 factory
来创建这个 aggregate root
的新实例,其中初始化了默认值,并输入已验证。
现在我注意到我创建的工厂对于存储库来说是不够的,因为它需要提供更具体的信息(与
entities
和 value object
aggregate
使用相关)。
项目中的存储库层需要创建聚合根的实例,以便它可以重用其存储的数据,并返回聚合图的实例,是吗?
存储库是一种外观模式:它提供了内存中存在聚合集合的错觉。换句话说,我们向客户隐藏了聚合来源的详细信息。
如果您的存储库与实现该幻觉所需的方法分开打包,那么可以;其他代码也将能够访问这些方法来创建聚合的瞬态表示。
例如,存储库实现可能在运行时依赖于工厂,该工厂接受通用数据结构作为输入并返回“根”实体的实例。
使用已发布的方法来创建聚合的瞬态实例,然后将这些实例“存储”在存储库中的客户端代码实现是相当常见的。
这并不违反 DDD 的任何“规则”。 (DDD 并没有真正的“规则”,因此它有“模式”,当上下文需要它时,它会稍微弯曲。“蓝皮书”的第 5 章和第 6 章描述了模式,而不是规则。)
也就是说,是的:许多编程语言只为包提供粗粒度的访问控制。如果人们使用不应该使用的公共/发布方法是一个重大问题,那么您需要采取其他对策来解决该问题。