一、为什么你需要DDD?传统架构的致命痛点
在Java后端开发中,绝大多数项目都采用经典的三层架构:Controller→Service→DAO。这种架构在简单CRUD场景下高效易用,但随着业务复杂度提升,会暴露出致命问题:
- Service层无限膨胀:一个Service类动辄几千行,逻辑耦合严重
- 业务与技术深度绑定:以数据库表为核心设计,一旦表结构变更全链路代码都要修改
- 团队协作成本高:产品、开发、测试没有统一的业务术语
- 迭代效率指数级下降:新增需求需通读全量代码,最终陷入"不敢改、改不动"
二、DDD核心本质
DDD的本质不是一套架构规范,而是一种以业务领域为核心的设计思想:先搞清楚业务是什么、业务规则有哪些,再基于业务去设计技术实现。
核心目标有两个:
- 统一语言:让整个团队使用同一套业务术语,消除沟通偏差
- 边界隔离:把复杂业务拆分成多个独立边界,高内聚低耦合
三、DDD战略设计:划清业务边界
3.1 通用语言(Ubiquitous Language)
统一语言是团队在特定业务边界内使用的、无歧义的业务术语集合。反例:产品叫"订单履约",开发代码里写OrderSendService,数据库表叫t_delivery,完全是三套不同的语言。
3.2 限界上下文(Bounded Context)
限界上下文是通用语言的边界,也是业务的最小自治单元。以电商系统为例:
- 订单限界上下文:订单创建、支付、发货、完成、取消
- 库存限界上下文:库存查询、扣减、归还、盘点
- 支付限界上下文:支付渠道对接、流水管理、退款处理
- 用户限界上下文:用户信息、会员等级、收货地址
3.3 上下文映射
核心有3种映射关系:合作关系、客户-供应商关系、防腐层(ACL)关系。防腐层尤其重要——当对接遗留系统时,通过防腐层隔离旧系统的影响,保护自身领域模型的纯净性。
四、DDD战术设计:落地代码实现
4.1 实体与值对象
实体:有唯一标识(如订单号)和完整生命周期的业务对象。
值对象:仅关注自身的值,无独立生命周期(如收货地址、支付金额)。
4.2 聚合与聚合根
聚合是一组相互关联的实体和值对象的集合,聚合根是聚合的核心控制点。以订单管理为例:订单本身就是聚合根,围绕它的订单商品、收货信息等构成订单聚合。
4.3 领域服务与领域事件
领域服务处理不属于单个实体的跨实体业务逻辑;领域事件是实现跨领域协作的关键,通过事件流转实现松耦合。
4.4 仓储模式
仓储封装了数据访问逻辑,让领域模型完全独立于持久化技术,是实现领域层与技术层解耦的关键。
五、落地方案:分层架构与六边形架构
四层架构:表现层 → 应用层 → 领域层 → 基础设施层,确保关注点分离。
六边形架构(端口与适配器):领域模型处于中心,外部依赖通过适配器接入,天然适配事件驱动机制。
六、总结
DDD不是银弹,它最适合业务逻辑复杂、需要长期维护的系统。对于简单CRUD场景,三层架构仍然是最务实的选择。关键是根据业务复杂度做出合理选择,不要为了DDD而DDD。
评论 (0)