知识卡片

仓储代码违反常规分层放进聚合目录:为聚合整体重组让步

普通读书笔记卡

内容

按照DDD分层架构的常规归属,仓储(Repository)本应该属于基础层——它负责的是数据持久化这类基础资源访问能力。但书中的微服务代码模型做了一个刻意违反这条常规分类的决定:把仓储相关代码放进了领域层的聚合目录内部,而不是放进infrastructure基础层目录。理由是聚合和仓储天然是一对一的关系,如果把两者的代码分别放在领域层和基础层两个物理位置,未来某个聚合需要在不同限界上下文或微服务之间做整体迁移或重组时,就必须同时去两个不同目录里各自搬迁一部分代码,操作繁琐且容易遗漏;而如果把仓储代码和这个聚合的领域逻辑代码放在同一个目录下,聚合就成为了一个包含”领域层业务逻辑+基础层数据处理逻辑”的、可以整体搬迁的独立单元,日后要拆分或迁移这个聚合时,直接把整个目录搬走即可。书中特别说明这个安排不会破坏依赖倒置——即使仓储实现代码物理上挪到了聚合目录里,聚合内部的业务逻辑依然是通过调用仓储接口来访问底层资源,接口和实现之间的依赖方向没有变。这个案例给出一条通用启示:代码的物理组织方式(放在哪个目录)可以为了某个更重要的目标(这里是”聚合能作为整体搬迁的最小单元”)而适当偏离教科书式的分层归类,只要真正重要的依赖方向和职责边界没有被破坏。

参考来源

- 位置:第14章《如何用DDD设计微服务代码模型》"14.2.2 各层代码目录","3. 领域层"(源文件:_epub-src/OEBPS/Text/chapter4-3-2-2.xhtml) - 结论依据:原文说明"按照DDD分层架构,仓储本应该属于基础层。但为了在微服务架构演进时保证聚合代码重组的便利,这里将仓储相关代码也放到了领域层的聚合目录中。这是因为聚合和仓储总是一对一的关系……当聚合需要在不同的限界上下文或微服务之间进行代码重组时,我们就可以以聚合代码包为单元,进行整体拆分或者迁移",直接支撑本卡片结论。 - 原始内容:按照DDD分层架构,仓储本应该属于基础层。但为了在微服务架构演进时保证聚合代码重组的便利,这里将仓储相关代码也放到了领域层的聚合目录中。这是因为聚合和仓储总是一对一的关系,将领域模型和仓储的代码组合在一起后,就是一个包含了领域层领域逻辑和基础层数据处理逻辑的聚合代码单元。