Domain driven design 为什么存储库方法应该接受域实体作为参数?

Domain driven design 为什么存储库方法应该接受域实体作为参数?,domain-driven-design,Domain Driven Design,假设我们有单独的读模型,这样我们只在写端使用存储库,而不在读端使用存储库。(这个问题都是关于写端的) 另外,让我们假设我们的目标之一是以只公开行为而不公开状态的方式进行完整的聚合/实体封装。(意思是说,没有能手/能手) 接下来,假设我们不想使用ORMs或反射从存储库中获取聚合内部构件 显然,剩下的解决方案之一是聚合本身将其完整状态公开为VO/poco,并将其移交给存储库。然后,存储库将知道如何将它映射到DAO并保存它 现在,在许多地方,我读到存储库应该接受聚合本身 问题是:为什么?聚合公开其状态

假设我们有单独的读模型,这样我们只在写端使用存储库,而不在读端使用存储库。(这个问题都是关于写端的)

另外,让我们假设我们的目标之一是以只公开行为而不公开状态的方式进行完整的聚合/实体封装。(意思是说,没有能手/能手)

接下来,假设我们不想使用ORMs或反射从存储库中获取聚合内部构件

显然,剩下的解决方案之一是聚合本身将其完整状态公开为VO/poco,并将其移交给存储库。然后,存储库将知道如何将它映射到DAO并保存它

现在,在许多地方,我读到存储库应该接受聚合本身

问题是:为什么?聚合公开其状态的VO有什么问题,将其交给存储库并让repo基于它进行保存

好处是完全清晰的聚合封装

聚合公开其状态的VO有什么问题,将其交给存储库并让repo基于它进行保存

这种方法违反了领域建模思想的一些其他假设

其中一个假设是,关键业务逻辑和“管道”应该分开。您需要获取聚合的可序列化表示,这是一个意外的事实,因为您正试图将状态写入稳定的存储(如果将聚合缓存在内存中,则该步骤完全没有必要)

第二个假设是,使用“对象”对域进行建模是一个好主意。如果您使用的是函数方法,那么您当然会保存值,而不是对象

我认为,这有助于记住,我们编写的解决方案的背景在过去15-20年中发生了很大变化。对于包含许多交互的长会话的本地化应用程序来说有意义的模式对于分布式无状态应用程序来说不一定有意义,反之亦然

这种模式会导致牺牲聚合封装

不,它没有-在先前约定的表示中向对象请求某些信息的副本并不违反封装。例如,见


但是,它需要适合两个不同合作者的接口:关心业务规则的应用程序和关心表示持久性的存储库。

请提供一个简单的示例并澄清VO代表什么?当然。它将是一个表示聚合状态的不可变值对象。通过将业务/管道和oop与函数式编程分离,您带来了非常有价值的观点。关于分离管道,我不确定的是,它们是否通过接受聚合的回购协议分离,因为这种模式会导致牺牲聚合封装。因此,它看起来也不理想,是吗?长会话应用程序确实与分布式应用程序有很大不同,但我认为最大的区别体现在设计聚合及其边界上。要求对象以先前商定的表示形式获取某些信息的副本并不违反封装。-那么,这是否意味着您在说聚合根暴露其状态的值对象以实现持久性是好的呢?