You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DDD架构中Repository应归属于领域层还是应用层?

关于Repository接口的分层归属

结论非常明确:Repository的抽象接口必须定义在Domain Layer(领域层),这是DDD权威定义和依赖倒置原则的共同要求:

  • 蓝皮书(Eric Evans《领域驱动设计》)将Repository明确定位为领域层的核心构造,核心作用是为领域逻辑屏蔽持久化细节,提供类似内存集合的聚合访问入口。
  • 你提到的红皮书(Vaughn Vernon《实现领域驱动设计》)中“领域服务通过Repository读取聚合完成组合校验”的表述,本质就是这个规则的落地场景:如果Repository接口不定义在领域层,领域服务就需要依赖外层的持久化实现,直接破坏分层架构的依赖方向,违反依赖倒置原则。

注意要区分接口和实现:Repository的具体持久化实现(比如关系型数据库访问实现、缓存实现)归属基础设施层,依赖方向是基础设施层实现领域层定义的Repository接口,而非领域层反向依赖基础设施。

关于领域层Repository接口的设计规则

两本权威著作对领域层Repository的设计有明确约束,并非可以随意定义,核心规则如下:

  • 操作边界严格限定为聚合根:Repository的所有读写操作只能针对聚合根实例,不能单独返回聚合内部的实体、值对象,所有对聚合内部元素的访问都必须通过聚合根入口完成,保证聚合的一致性边界不被破坏。
  • 查询方法不局限于按ID查询,但必须服务于领域逻辑需求:除了按ID获取聚合之外,你完全可以根据领域场景定义按业务唯一键查询、按领域属性条件批量查询聚合的方法,但这些方法的返回值必须是完整的聚合根实例。那些返回非聚合投影DTO、跨聚合联表的查询需求,属于CQRS查询模型的职责,不应该放在领域层的Repository接口中。
  • 接口语义贴合集合特性,不暴露持久化细节:不要在接口中定义带有持久化实现特征的方法,比如避免使用insert、update这类直接映射数据库操作的命名,应该采用和内存集合一致的语义命名,比如add(新增聚合)、save(持久化聚合变更)、remove(删除聚合)、findByXxx(查询聚合)。
  • 接口只承担持久化抽象职责,不掺杂业务逻辑:Repository接口只定义聚合的存取相关方法,不要把校验、计算等业务逻辑放到Repository实现中,业务逻辑的归属始终是聚合根、领域服务。

内容的提问来源于stack exchange,提问作者Saeed Farahi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 20:18:29