DDD - 将域对象存储在面向文档的存储中,PostgreSQL,MongoDB

时间:2016-08-04 22:13:32

标签: php mongodb postgresql doctrine-orm domain-driven-design

关于DDD的另一个问题。考虑到坚持我的聚合(我不想使用事件采购)我搜索了互联网,发现Vaughn Vernon非常有趣article。简而言之 - 作者赞扬使用面向文档的存储(特别是PostgreSQL)将Domain Objects与整个结构存储的概念。

我的问题是 - 因为我是DDD概念的新手 - 使用这种方法在DDD开发中是否常见?我的意思是使用面向文档的存储将聚合存储为序列化的完整文档? 我认为以嵌套方式持久聚合比使用ORM加载和映射更接近DDD的想法。对于域对象的嵌套结构,文档格式似乎更自然和有弹性。 除了上面提到的文章,我还没有找到关于这个概念的更多评论。

接下来的问题是 - 在PHP环境中 - 有没有人试图将它与Doctrine2联系起来?它似乎可以自动序列化POPO,并且可以某种方式使用ValueObjects。

提前致谢!

2 个答案:

答案 0 :(得分:2)

  

我的问题是 - 因为我是DDD概念的新手 - 使用这种方法在DDD开发中是否常见?

是的 - 是的。

要记住一件事:DDD旨在帮助正确建模业务。如果更改是域的一个有价值的属性(如果该项目是对您的业务具有竞争优势的项目可能就是这种情况),那么您需要考虑的是聚合序列化轻松迁移到改进的模型。换句话说,如何将旧模型的表示映射到新模型?

如果您采用这种方法,那么您可能还想研究;对于写用例来说,数据blob是令人满意的,但是只写域模型并不能提供很大的商业价值。您可以更轻松地开发最终一致的读取模型,而不是尝试根据文档存储的需求构建复杂的投影。

您看到类似方法的另一个地方是使用事件源聚合的解决方案;写入是通过附加到历史来实现的,并且任何给定更改中涉及的实际状态通常存储在blob中。

答案 1 :(得分:1)

正如您可能从本书中所知,聚合持久性是通过使用Repository模式完成的。其目的是隐藏域模型中的持久性技术和实现细节。

根据定义,存储库只能存储和检索整个聚合。这就是为什么弗农提到类似文档的存储作为一个好的候选人。使用RDBMS进行聚合持久性时,通常最终会使用ORM和复杂映射。当走这条路径时,你会得到复杂的模式,而不是最佳的查询,繁琐的更新逻辑等等。

这确实是CQRS特别是在DDD社区中引起关注的原因,因为传统的"集合式"存储库缺乏查询许多聚合并检索一些报告风格的能力。数据。蓝皮书提出了一些相当复杂的方法。 CQRS消除了这个问题,但需要相当多的额外工作来保持两个模型的同步。

还有另一种处理方法。通常,域模型不需要在聚合上运行查询。 A"客户"域模型负责发送一个正确的"命令"或请求域模型由某种应用程序服务处理。这个"客户"部分或"适配器"在六边形体系结构中,可以在域持久性数据库上运行查询而无需使用任何存储库。它也是一种CQRS,但使用一个数据库。