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

DDD与整洁架构:为何不在应用层定义仓储接口?

关于Go中整洁架构+DDD下仓储接口定义位置的思考与实践

你的思路完全站得住脚,本质是坚持领域层的纯粹性,把“数据持久化”这个跨层依赖彻底归为应用层的职责,这和整洁架构“依赖向内”的核心原则高度契合。

一、应用层定义仓储接口的核心优势

  • 领域层彻底解耦持久化:领域层只需要聚焦Item等实体的业务规则(比如状态流转、价格校验逻辑),完全不用关心“数据从哪来、存到哪去”,这才是真正的“业务与基础设施分离”。
  • 应用层按需定义接口:应用层作为用例的发起者,最清楚自己需要什么操作(比如“获取某个状态的Item”“批量保存Item”),就地定义的仓储接口更贴合实际用例,不会出现领域层定义一堆用不上的方法,避免过度抽象。
  • 聚合根创建的灵活性:应用层负责收集实体/值对象的原始数据,传递给领域层的工厂函数创建聚合根,这种方式完全符合“领域层只负责业务规则校验”的原则——工厂函数只需要确保聚合根创建时符合业务约束(比如Item的价格不能为负),不用关心数据来源(是DB查询来的,还是API请求来的)。

二、传统“领域层定义仓储”的出发点

很多DDD资料推崇领域层定义仓储,核心是为了让领域模型拥有“主动持久化自身”的能力,比如聚合根的Save()方法内部调用领域仓储。但这种设计其实混淆了“业务行为”和“基础设施行为”:聚合根的核心是业务逻辑,持久化只是它的“副作用”,不该耦合到领域模型里。

在Go这种偏向简洁、避免OOP过度封装的语言里,这种传统模式反而显得笨重——你得给每个聚合根都套一层仓储依赖,违背了Go的“组合优于继承”“简洁至上”的风格。

三、实操中的注意事项

  • 仓储接口要面向领域实体:不管在哪层定义,仓储接口的输入输出都应该是领域层的Item聚合根/实体,而不是数据库的DTO,这样才能保证应用层和领域层的交互是基于领域模型的。
  • 避免应用层侵入领域逻辑:应用层只负责“调度”——收集数据、调用领域工厂、调用仓储,绝对不能在应用层实现业务规则(比如判断Item是否符合上架条件),这些必须留在领域层。
  • 依赖反转的落地:应用层定义仓储接口,基础设施层(比如DB实现、缓存实现)去实现这个接口,这完全符合依赖反转原则——高层模块(应用层)定义抽象,低层模块(基础设施)依赖抽象,而不是反过来。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 19:32:49