当前位置: 首页 > news >正文

DDD 中的代码组织:按技术层分 vs 按领域模块分,哪种才是正解?

前言

在实践领域驱动设计(DDD)时,你可能见过两种截然不同的代码组织方式:一种是传统的按技术层划分文件夹,另一种是按业务模块划分文件夹。两种写法的人都声称自己在做 DDD,那到底哪种更合理?本文来聊聊这个问题。


一、两种风格长什么样?

风格 A:按技术层划分

src/ ├── controllers/ │ ├── OrderController.java │ ├── UserController.java │ └── ProductController.java ├── services/ │ ├── OrderService.java │ ├── UserService.java │ └── ProductService.java ├── repositories/ │ ├── OrderRepository.java │ ├── UserRepository.java │ └── ProductRepository.java └── entities/ ├── Order.java ├── User.java └── Product.java

特点:所有 Controller 放一起,所有 Service 放一起,所有 Repository 放一起。代码按"技术职责"归类。

风格 B:按领域模块划分

src/ ├── order/ │ ├── entity/ │ ├── service/ │ ├── repository/ │ └── event/ ├── user/ │ ├── entity/ │ ├── service/ │ ├── repository/ │ └── event/ └── product/ ├── entity/ ├── service/ └── repository/

特点:每个业务领域独占一个文件夹,内部再按技术层细分。代码按"业务归属"归类。


二、两种都算 DDD 吗?

严格来说,两种都可以算 DDD。

DDD 的核心在于战略设计(限界上下文、通用语言)和战术设计(聚合、实体、值对象、领域事件等),并没有强制规定文件夹必须怎么组织。只要你的代码遵循了聚合隔离、分层架构等原则,文件夹结构属于实现细节。

但——

按领域模块划分,才是 DDD 社区推荐的做法。原因往下看。


三、为什么按模块分更优?

维度按技术层分按领域模块分
可读性找一个功能需要跨 3-4 个文件夹打开一个文件夹就能看到完整业务
维护性修改一个功能,改动散落各处改动集中在一个目录内
扩展性新增模块的文件分散在各层新建一个文件夹即可
拆分微服务需要大量重构抽离直接把文件夹拎出去
聚合隔离容易跨聚合乱引用天然形成物理隔离边界
团队协作多人改同一文件夹,冲突频繁各团队各守一个模块目录

核心原因:与 DDD 的限界上下文天然契合

DDD 强调:

聚合之间在代码上应当完全隔离,聚合之间通过应用层协调。

按模块划分文件夹,让限界上下文在物理结构上可见。一个文件夹就是一个限界上下文(或聚合),边界清清楚楚。而按技术层划分时,这个边界是隐性的,全靠开发者自觉——时间一长,跨模块调用必然泛滥。


四、为什么还有人按技术层分?

几个常见原因:

  1. MVC 惯性:从 Spring MVC / Rails 等框架入门,习惯了 controller-service-dao 三层结构,迁移到 DDD 时直接照搬。

  2. 项目规模小:只有 2-3 个实体时,按模块分反而显得过度设计,按层分更简洁直观。

  3. “伪 DDD”:口头上说在做 DDD,实际思维还是面向数据库的 CRUD,时间一长项目会退化成"披着 DDD 外衣的 MVC"。

  4. 框架脚手架默认生成:很多脚手架默认生成的就是按层分的结构,开发者没有主动调整。


五、推荐的项目结构

结合 DDD 四层架构 + 按模块划分,推荐如下结构:

src/ ├── interfaces/ # 用户接口层(对外暴露) │ ├── rest/ │ │ ├── OrderController.java │ │ └── UserController.java │ └── dto/ │ ├── application/ # 应用层(用例编排,不含业务逻辑) │ ├── order/ │ │ └── OrderApplicationService.java │ └── user/ │ └── UserApplicationService.java │ ├── domain/ # 领域层(核心业务逻辑) │ ├── order/ # 订单限界上下文 │ │ ├── entity/ │ │ │ ├── Order.java │ │ │ └── OrderItem.java │ │ ├── valueobject/ │ │ │ └── Money.java │ │ ├── event/ │ │ │ └── OrderCreatedEvent.java │ │ ├── repository/ │ │ │ └── OrderRepository.java # 接口定义 │ │ └── service/ │ │ └── OrderDomainService.java │ │ │ └── user/ # 用户限界上下文 │ ├── entity/ │ ├── valueobject/ │ ├── repository/ │ └── service/ │ └── infrastructure/ # 基础设施层(技术实现) ├── persistence/ │ ├── OrderRepositoryImpl.java │ └── UserRepositoryImpl.java ├── messaging/ └── config/

这个结构的好处

  • 领域层是绝对核心,不依赖任何外部框架
  • 每个限界上下文一个文件夹,边界清晰
  • 架构演进友好:将来拆微服务时,domain/order/整个目录迁移即可
  • 新人友好:看目录结构就能理解业务划分

六、什么时候用哪种?

场景建议
项目只有 1-3 个实体,且不会扩展按技术层分就够了,别过度设计
中大型项目,多个业务领域按模块分,必须的
团队多人协作按模块分,减少代码冲突
预期未来要拆微服务按模块分,提前做好物理隔离
学习 DDD 初期练手直接用按模块分,养成好习惯

七、总结

结论说明
两种都"算" DDDDDD 不强制规定文件夹结构
但按模块分是推荐做法让限界上下文在代码物理结构上可见
按技术层分的本质问题业务边界隐性化,长期维护成本高
一句话原则代码结构应该反映业务结构,而不是技术结构

如果打开你的项目目录,一个不懂技术的产品经理都能大概看出"这里是订单、这里是用户、这里是商品",那你的代码组织就对了。


如果你正在从传统 MVC 项目向 DDD 转型,第一步不妨就从调整文件夹结构开始——把散落在各技术层的同一业务代码,收拢到同一个模块目录下。这一步虽然简单,但对团队理解"领域边界"的帮助是立竿见影的。

http://www.jsqmd.com/news/862787/

相关文章:

  • Light: Science Applications | 从平坦能带到量子行走:非阿贝尔Thouless泵浦的新篇章
  • 搜索引擎精准找免费行业报告?掌握这些关键词技巧就够了
  • 随钻连斜传感器操作手册:定向探管安装调试、故障排查与保养要点
  • 2026最新诚信优选 安庆市迎江区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 如何让Mac永不休眠:自动鼠标移动器的终极指南
  • 【零基础部署】Docker 部署 n8n 自动化工作流保姆级教程
  • 深入解析Hash碰撞:原理、成因与主流解决方案
  • 今天实测有效!2026淘宝京东天猫618红包领取口令最新推荐怎么天天领618淘宝京东天猫红包?
  • 2026最新诚信优选 安顺市平坝区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026最新诚信优选 安顺市西秀区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 2026年设计行业必备!兴弘实战设计培训班速成班究竟有多牛?
  • HYPE分布式水文模型建模方法与案例分析实践技术应用:精准完成子流域划分;系统解锁土地利用、土壤数据提取技巧
  • 轻量化无广告!开箱即用 M3U8 在线播放器,调试预览一步到位
  • fpc参数说明
  • 2026最新诚信优选 安阳市龙安区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • 开发一个小程序需要多少钱?2026 行业收费标准及石家庄优质开发服务商推荐
  • # 如何从控制台获取
  • 终极Mac微信插件:消息防撤回与多开登录完整指南
  • Google三星AI眼镜来了,开发者该关注什么
  • 向日葵远程控制16.5发布,“免密远控”功能登场便捷又安全
  • 2026年企业AI落地新趋势!RAG知识库实战指南:环境搭建到生产部署全解析
  • 英雄联盟Akari助手:提升游戏效率的终极开源工具
  • WTEW的操作记录
  • 初次体验 Taotoken 从注册到完成第一个 Python API 调用的全过程
  • 2026最新诚信优选 安阳市文峰区黄金回收白银回收铂金回收彩金回收门店TOP5排行榜+联系方式推荐_转自TXT - 盛世金银回收
  • BeeWorks 的 “链端管“ 安全体系到底有多强?
  • 数据结构——带懒标记的线段树
  • VSCode 降级到旧版本如何关闭自动更新提示弹窗
  • MatMul 算子在昇腾 NPU 上的优化实践:从原理到实战
  • 安全与稳定并重:DeviceXPlorer OPC Server的工业级安全策略