夏有木工作室夏有木工作室夏有木工作室
  • 首页
  • 博客
  • 关于我们
  • 联系我们
夏有木工作室夏有木工作室夏有木工作室
全部文章/
架构设计

为什么写不好 DDD 代码?

EricEric
2025/01/14
·5 分钟阅读 (1,551 字)·

深度剖析为什么大部分团队写不好 DDD,从建模思维、业务边界侵蚀到防腐层设计,解析领域驱动的核心痛点与破局解法。

目录

  • DDD 对 MVC 的演进
  • 1. 依赖反转
  • 2. 业务逻辑拆分成 Application 层 和 Domain 层
  • 为什么写不好 DDD 代码呢?
  • 1 业务理解不足,领域模型脱离实际
  • 2. 团队技术能力不均,实践 DDD 时急功近利
  • 3. 上下文边界不清,领域模型与技术耦合
  • 4. CRUD 场景多,DDD 显得繁琐
  • 建议
  • 最后
  • 推荐阅读
  • 附录
  • 架构设计推荐阅读

自从 DDD 火起来之后,个人主导的项目以及经历的项目绝大部分都采用的是 DDD 模式,今天就来聊一聊,DDD 模式与 MVC 模式的差异以及我对于 DDD 模式的一些看法。

DDD 对 MVC 的演进

1. 依赖反转

根据依赖倒置原则(高层模块不应该依赖于低层模块,两者都应该依赖于抽象,抽象不应该依赖于细节,细节应该依赖于抽象)。

带来的变化:

  • 基础设施层的接口定义在其他层。基础设施层只实现这些接口。

  • 具体出现依赖反转的场景如下:

    a)在 Domain 层新增了对 Repository 定义的接口。

    b)在 infrastructure 层新增了对 Repository 仓储的实现。

    c)Application 层不再依赖 infrastructure 层。

依赖反转的缺点:

  • Application 层无法直接调用 infrastructure 层,需要经过 Domain 层,再反转调用到 infrastructure 层,导致增加了不同层的数据对象,以及这些对象之间的转换。
  • 思维模式的转变, Api --> Biz Logic --> Db 这种直接调用模式深入人心,一时很难进行转变,而且很多时候确实简单高效,引起很多开发对于 DDD 模式的质疑。

依赖反转的优点:

  • 各层代码边界更加清晰

  • 业务逻辑层不再依赖 infrastructure 层,更容易编写单元测试。

2. 业务逻辑拆分成 Application 层 和 Domain 层

带来的变化:

  • 新增一个 Domain 层。
  • 将业务逻辑层中的领域相关业务提取到新增的 Domain 层。

新增 Domain 层的缺点:

  • 增加了 Domain 层后,domain 层的领域对象需要转换。
  • 对大批量的修改或者性能要求很高的场景支持不够友好。
  • DDD 模式下更加关注单个聚合的生命周期,对于数据的创建和修改,采用的全量的方式,在高并发场景下非常容易出现 ABA 的情况。
  • 对于团队成员的要求较高,需要对于 DDD 有一定的理解,很容易出现采用的是 DDD 模式,但是实现的是 MVC 代码,起到了反作用,增加了修改代码的修改量和复杂度。

新增 Domain 层的优点:

  • 充分理解 DDD 的设计模式后,通过统一的方法论,提高代码设计质量。
  • 保障设计与代码的一致性,提升工程质量。
  • 通过业务与基础设施的解耦,对单体测试的友好性。

为什么写不好 DDD 代码呢?

1 业务理解不足,领域模型脱离实际

在国内项目中,产品需求变动频繁,开发者和业务方之间的沟通往往缺乏深入性和连续性。开发团队为了赶进度,容易忽略领域建模的时间投入,导致领域模型不准确、不完整,甚至完全背离业务需求。

导致领域模型成为形式化的存在,无法清晰表达业务逻辑,开发过程中经常需要额外编码来“弥补”模型的缺陷,增加了代码复杂性和维护成本。

2. 团队技术能力不均,实践 DDD 时急功近利

团队成员的技术能力参差不齐,部分开发者对 DDD 理解不足,仅从“分层架构”角度解读 DDD,而忽视了领域建模和限界上下文的核心思想。同时,项目往往处于紧张的交付节奏中,团队急于应用 DDD,导致模型设计草率,甚至过度复杂化。

导致系统设计过度臃肿或不符合实际业务场景,领域层逻辑分散在应用层或基础设施层中,开发和维护的难度加大。

3. 上下文边界不清,领域模型与技术耦合

国内许多项目因技术驱动而非业务驱动展开,比如优先选择微服务架构、ORM 框架或某种技术解决方案,而在开发过程中再去适配领域模型。限界上下文未能准确划分,领域模型混杂多个上下文的概念,领域逻辑与数据存储和服务接口深度耦合。

导致系统内的领域逻辑难以维护和扩展,代码质量参差不齐,随着业务发展,重构成本越来越高,团队逐渐对 DDD 失去信心。

4. CRUD 场景多,DDD 显得繁琐

在很多复杂业务系统中,尽管整体业务看似复杂,但核心功能可能仍以 CRUD(增删改查)为主,如管理后台、数据录入系统等。这种情况下,直接使用简单的事务脚本或基于传统分层架构的设计就能很好地满足需求,而采用 DDD 的分层与模型设计反而显得繁琐。

强行使用 DDD,导致将简单的逻辑拆分成复杂的聚合、实体、值对象和服务,导致代码臃肿,开发效率下降,且团队对这些额外设计产生不满。

建议

  1. 当项目的业务场景简单,核心逻辑就是 CRUD,直接采用传统的分层架构(Controller-Service-Repository),避免不必要的复杂性。
  2. 当项目的业务复杂度高,但 CRUD 仍占据主导,可采用灵活的分层设计,将 DDD 用于处理关键的复杂业务逻辑,而其他部分仍然保持轻量化设计,做到局部复杂化、全局简单化。
  3. 若采用灵活的分层架构,可以结合 MVC 和 DDD 有优缺点进行整合,团队内部达成一致。

最后

DDD 的核心价值在于解决复杂的领域问题,但对于以 CRUD 操作为主的场景来说,强行使用 DDD 会导致效率低、维护成本高、团队抵触。正确的做法是根据实际需求权衡设计方法,避免理论驱动开发,做到“适场景而用,避免过度设计”。

推荐阅读

DDD 分层架构落地实践

应用分层架构最佳实践:Alibaba COLA 4.0

附录

DDD 工程代码样例:

image-20250113下午31933832

架构设计推荐阅读

如果你对领域驱动设计(DDD)、分层架构与企业级系统建模感兴趣,推荐阅读:

  • 应用架构最佳实践:Alibaba COLA 4.0
  • DDD 分层架构落地实践
  • 为什么写不好 DDD 代码?

👉 查阅更多企业级系统设计与工程实战,欢迎访问 架构设计专栏完整目录。

上一篇

从 0 到 1 开发一个小程序所需要准备的资质

下一篇

使用 Sa-Token 平替 Spring Security,告别繁琐的认证与鉴权

更多文章

使用 Sa-Token 平替 Spring Security,告别繁琐的认证与鉴权

使用 Sa-Token 平替 Spring Security,告别繁琐的认证与鉴权

对比传统 Spring Security 的复杂繁重,分享使用轻量 Sa-Token 框架实现无痛多端鉴权、单点登录与路由拦截的最佳实践。

EricEric
2025/01/15
良好的异常处理设计:系统稳定性的基础保障

良好的异常处理设计:系统稳定性的基础保障

探讨企业级后端的全局异常体系设计,规范业务错误码、状态流转异常捕获与微服务防御性兜底保障。

EricEric
2024/11/27
MySQL 创建高性能的索引

MySQL 创建高性能的索引

深入 MySQL 索引底层原理,总结 B+ 树特性、最左匹配原则、覆盖索引与排查慢查询的高效索引设计军规。

EricEric
2024/09/26
夏有木工作室夏有木工作室夏有木工作室

专业软件开发技术伙伴,帮助客户快速构建出高质量的软件产品。

GitHubGitHubEmail
Built with夏有木工作室夏有木工作室夏有木

川公网安备51012202002478号|蜀ICP备2025156031号-1

产品
  • 夏有木进销存
工具
  • 夏有木微信公众号排版
资源
  • 博客
  • 更新日志
公司
  • 关于我们
  • 联系我们
法律
  • Cookie政策
  • 隐私政策
  • 服务条款
© 2026 夏有木工作室 All Rights Reserved.