说一下你对于 DDD 的了解?
- 标签:DDD、Spring Cloud、微服务、后端
🏛 业务架构师
我对 DDD(领域驱动设计)的理解分四层,重点讲它为什么是业务架构师的核心武器:
1. 战略设计(最有价值的部分):统一语言(Ubiquitous Language)+ 限界上下文(Bounded Context)+ 上下文映射。和业务方用同一套词汇("预授权"对开发和业务是同一个含义),按业务语义划分边界,再用映射明确上下文间关系(防腐层、上下游)。这一步直接决定微服务怎么拆——比按技术分层拆靠谱一个量级。
2. 战术设计:限界上下文内的建模工具——实体、值对象、聚合根(一致性边界,外部只能持有引用)、领域事件、领域服务、仓储。聚合的纪律:跨聚合不用强事务,用领域事件最终一致——这恰好是分布式事务的正确替代。
3. 落地结构:经典的四层(用户接口/应用层/领域层/基础设施),依赖倒置让领域层不依赖技术细节。Spring 生态下常配合 Spring Modulith 做模块化单体,或按上下文拆微服务。
4. 我的实战体会(讲出这个才有说服力):
- DDD 的成本在前期的事件风暴、领域 workshops——需要业务专家深度投入;收益是需求沟通成本下降 + 模型稳定性(技术框架换三代,订单模型还在);
- 不是所有系统都配 DDD:复杂业务逻辑、长生命周期的核心域(交易、风控、履约)值得;简单 CRUD 用它就是仪式感负担——按域分级投入:核心域 DDD、支撑域简化、通用域直接买;
- 最常见的失败模式:只有战术模式的"形"(到处是聚合类),没有统一语言的"神"——代码里还是数据思维。
🏗 系统架构师
两个层面讲:
战略设计(架构师主战场):限界上下文(Bounded Context)、统一语言(Ubiquitous Language)、上下文映射。同一个词「商品」在交易、库存、营销上下文里语义不同——微服务拆分边界应与限界上下文对齐,这是我做服务拆分最可信的依据,比按技术层拆靠谱得多。上下游关系用映射模式表达,**防腐层(ACL)**隔离外部模型,防止模型污染。
战术设计:实体、值对象、聚合根(一致性边界:外部只持有聚合根引用,跨聚合走领域事件最终一致)、仓储、领域事件、领域服务。
我的实践判断:
- DDD 的最大 ROI 在战略层——划分边界防分布式单体;战术全套(事件溯源、CQRS)只在复杂领域值得,CRUD 系统套战术模式是过度设计;
- 落地路径:事件风暴(Event Storming)工作坊拉齐业务与开发对流程的理解,产出上下文图指导服务划分;
- 与微服务的关系:DDD 答「怎么拆」,微服务答「拆完怎么跑」。注意粒度对应关系:服务 ≈ 限界上下文,聚合是服务内边界——不是一服务一聚合,更不是一表一服务。
💻 全栈开发专家
DDD 分两层谈:
战略设计(宏观):核心是把业务划成限界上下文(Bounded Context),每个上下文有自己的统一语言——"订单"在交易上下文和履约上下文含义不同,各自建模。上下文映射定义集成关系(防腐层 ACL 隔离外部模型)。工程价值:限界上下文 ≈ 微服务拆分边界 ≈ 团队边界,这是"微服务怎么拆"最靠谱的方法论。
战术设计(微观):
- 实体 Entity:有唯一标识(Order,id 不变属性可变)
- 值对象 ValueObject:无标识不可变(Money 用值对象杜绝 double 精度事故)
- 聚合 Aggregate:一致性边界,外部只持聚合根引用;跨聚合用领域事件最终一致
- 仓储 Repository:持久化抽象,接口在领域层、实现在基础设施层
落地包结构(我们项目):interfaces(API 装配)→ application(用例编排、事务)→ domain(实体/领域服务,零框架依赖)→ infrastructure(仓储实现/MQ/缓存),依赖倒置的四层。
清醒观点:DDD 不是所有项目都上——CRUD 后台用事务脚本足够;复杂规则、长生命周期、多人协作的核心域才值得。国内最普遍的反模式是贫血模型(实体只剩 getter/setter,逻辑全在 Service),战术 DDD 的最低要求就是逻辑进实体。