明知山没虎

一个游手好闲的人

DDD是个什么鬼?一个老架构师的吐槽

2025-12-24

前言

做了十几年架构师,见过的项目不下百个,踩过的坑能绕地球三圈。最近几年,DDD(领域驱动设计)这玩意儿火得一塌糊涂,到处都是布道师在吹,仿佛不用DDD就不是好架构师似的。

说实话,我一开始也被忽悠得一愣一愣的,买书、听课、实践,折腾了好久。但越用越觉得不对劲,最后发现:这玩意儿就是个坑,而且是个深坑。今天就来好好聊聊为什么我觉得DDD是个大忽悠。

DDD到底在玩什么花样?

概念多得让人头大

你以为学个设计模式23个就够多了?DDD告诉你:那算什么,我有一大堆概念等着你:

  • 聚合根(Aggregate Root)

  • 值对象(Value Object)

  • 领域服务(Domain Service)

  • 应用服务(Application Service)

  • 仓储(Repository)

  • 工厂(Factory)

  • 领域事件(Domain Event)

  • ...

我去,这么多概念,光是理解就要花老长时间。更要命的是,这些概念的边界模糊得要死。

拿聚合根来说,什么时候该用?边界怎么划?问十个DDD专家能给你十一种答案。我见过为了划分一个用户聚合,团队开会讨论了三天,最后还是没个定论。这不是扯淡吗?

学习成本高得离谱

想学好DDD,你得具备:

  • 深厚的面向对象功底(大部分人连这个都没有)

  • 丰富的业务理解能力(这个更稀缺)

  • 抽象思维能力(天赋要求)

  • 大量实践经验(时间成本)

问题是,现在大部分程序员连基本的面向对象都没搞明白,继承、封装、多态用得乱七八糟,你让他们去理解DDD这套高深理论?纯粹是赶鸭子上架。

我见过太多团队,架构师画了一大堆UML图,定义了一堆领域模型,下面的开发看得云里雾里,最后还是按照老方法写增删改查,只是套了层DDD的壳子。

我们真正的问题在哪里?

面向对象用得稀烂

说句不好听的,国内大部分程序员的面向对象水平还停留在十年前。我经常看到这样的代码:

// 这样的"面向对象"代码随处可见
public class UserService {
    public void processUser(User user) {
        if (user.getType().equals("VIP")) {
            // 一大堆VIP逻辑
        } else if (user.getType().equals("NORMAL")) {
            // 一大堆普通用户逻辑
        } else if (user.getType().equals("PREMIUM")) {
            // 又是一大堆逻辑
        }
        // ... 还有更多if-else
    }
}

这哪是面向对象?这就是用Java语法写面向过程的代码!多态在哪里?职责分离在哪里?

建模思维缺失

更要命的是,大家根本不知道什么叫建模。我问过很多开发:

"你为什么要创建这个类?" "呃...因为需求文档里有这个实体"

"这个方法为什么放在这个类里?" "呃...感觉应该放这里"

完全没有从问题域的角度思考,没有考虑对象的职责和协作关系,纯粹是拍脑袋决定。

DDD不但没解决问题,还把水搅浑了

治标不治本

面向对象用得稀烂,建模思维缺失,这些是根本问题。DDD呢?它不去解决这些根本问题,反而在上面又盖了一层更复杂的理论。

就好比一个人连走路都没学会,你却要教他跳芭蕾舞。结果可想而知。

我见过无数项目,团队成员对面向对象的基本原则都搞不清楚,却要按照DDD的方式来组织代码。结果就是:

  • 代码层次多得要命

  • 抽象层次混乱

  • 职责分配不清

  • 接口设计混乱

过度设计成了家常便饭

DDD最大的副作用就是让程序员觉得不搞几层抽象就显得不专业。我见过为了处理一个简单的用户注册功能,搞出来十几个类的:

  • UserRegistrationDomainService

  • UserRegistrationApplicationService

  • UserRegistrationFactory

  • UserRegistrationRepository

  • UserRegistrationValidator

  • UserRegistrationSpecification

  • ...

我去,注册个用户而已,至于搞这么复杂吗?这不是设计,这是炫技!

实战中的血泪教训

项目A:电商平台的噩梦

去年接手了一个电商项目,前任架构师是个DDD狂热分子。整个项目严格按照DDD来设计:

  • 订单聚合包含17个类

  • 商品聚合包含21个类

  • 用户聚合包含13个类

  • 各种领域服务、应用服务、仓储满天飞

看起来很专业对吧?实际用起来呢?

  • 改个简单功能要动七八个文件

  • 新人看代码要跟迷宫一样

  • 性能问题一大堆(因为抽象层次太多)

  • 测试写起来要死要活

最后我花了三个月时间重构,把那些华而不实的抽象都砍掉,项目终于能正常运行了。

项目B:简单业务的复杂化

还有个更典型的例子,一个简单的内容管理系统,核心就是增删改查文章。结果架构师非要用DDD:

  • Article聚合根

  • ArticleContent值对象

  • ArticleTitle值对象

  • ArticleStatus值对象

  • ArticleDomainService

  • ArticleApplicationService

  • ArticleRepository

  • ArticleFactory

  • ArticleSpecification

我算了一下,为了实现一个简单的发布文章功能,需要创建9个类,写200多行代码。如果用传统方法,一个Service + 一个Entity就搞定,最多50行代码。

这是进步还是倒退?

什么才是正道?

先把基本功练扎实

与其折腾什么DDD,不如先把面向对象的基本功练扎实:

单一职责原则:一个类只做一件事,别什么都往里面塞 开闭原则:要扩展功能,加新类,别改老代码 里氏替换原则:子类要能完全替代父类,别搞奇怪的继承 接口隔离原则:接口要小而精,别搞大而全的上帝接口 依赖倒置原则:依赖抽象,不要依赖具体实现

这些原则看起来简单,真正理解并应用好,需要大量实践。把这些基本功练扎实了,比学一百个DDD概念都有用。

从简单开始,循序渐进

建模能力不是一天两天能培养出来的,得慢慢来:

  1. 先从简单业务开始:别上来就搞复杂系统,从简单的CRUD开始

  2. 关注对象职责:这个类应该负责什么?不应该负责什么?

  3. 重视接口设计:接口要稳定、易用,内部实现随便你怎么改

  4. 多实践,多反思:每个项目结束后,回头看看哪些设计是好的,哪些是坑

保持务实的态度

软件设计的目标是解决实际问题,不是炫技。好的设计应该是:

  • 简单直观:新人能快速理解

  • 易于维护:改功能不用动一大堆代码

  • 性能合理:别为了抽象牺牲性能

  • 符合业务:贴近实际业务场景

如果一个设计需要花大量时间向团队解释,那多半是过度设计了。

总结

DDD本身可能有些价值,但被过度神化了。对于大多数团队来说,与其花时间学习这些高深理论,不如踏踏实实把面向对象的基本功练好。

记住一句话:简单有效的设计胜过复杂炫酷的架构。别被那些高大上的概念忽悠了,实用主义才是王道。

作为架构师,我们的职责是让系统更简单、更稳定、更易维护,而不是显摆自己知道多少理论概念。DDD这种增加复杂度却不解决根本问题的东西,还是算了吧。

最后送给大家一句话:Less is More。简单的才是最好的。