DDD架构演进

DDD架构演进

核心主旨:MVC是按技术分层 ,DDD六边形架构是按业务分层;二者不是等价替换关系,是架构思想的升级,解决传统MVC失血模型、Service臃肿、业务逻辑和技术实现混杂的痛点。

来源:bugstack虫洞栈|小傅哥

一、传统MVC架构的问题

MVC分层:Controller → Service → DAO/POJO

  1. 失血模型:PO只是数据表映射,只有字段,没有业务行为;业务规则全部写在Service里。
  2. Service是大杂烩:流程编排、业务规则、数据库操作、第三方RPC调用、缓存逻辑全部揉在一起。
  3. 依赖方向混乱:业务逻辑直接依赖DB、中间件、外部接口,换存储、换第三方时改动巨大。
  4. 边界模糊:随着迭代,代码耦合严重,难以理解业务,不容易做单元测试。

MVC适合简单CRUD;业务复杂、规则多变、需要长期维护的系统,容易变成屎山。

二、DDD六边形架构分层

分层 职责要点
trigger 触发层 所有外部入口:HTTP接口、RPC、MQ消费、定时任务Job;只做参数校验、接收请求、异常包装,禁止写业务逻辑
api层 接口定义、DTO入参出参,对外契约
case(应用编排层) 应用流程编排,调度领域对象;只负责"先做A、再做B",不包含业务规则,不写核心判断
domain 领域层【核心】 充血模型:聚合、实体、值对象、领域服务、领域事件;存放不变的业务规则、业务约束、业务校验 ;只定义仓储抽象接口,不依赖数据库、RPC等外部技术
infrastructure 基础设施层 实现domain定义的抽象端口;包含DAO、数据库操作、Redis、RPC调用、防腐层ACL;适配外部技术
types通用层 枚举、常量、通用工具、基础值对象

✅ 依赖原则:向内依赖,外层依赖内层,领域层不依赖基础设施。

三、MVC 与 DDD 分层映射(重点,不是1:1)

重要前提:不能直接把MVC的包改名当成DDD,属于伪DDD;MVC一层往往要拆到DDD多个层。

  1. Controller
    对应:trigger + api
    Controller中原有的业务逻辑,要剥离到case/domain;trigger只保留入口能力。

  2. Service(MVC的Service)
    拆成三块:

    • 流程编排代码 → case应用层
    • 核心业务规则、业务行为 → domain领域服务/聚合内
    • DB、第三方调用的技术实现 → infrastructure
  3. DAO + POJO

    • DAO、数据库PO(和表一一对应)→ infrastructure
    • 业务实体、聚合根(充血、带业务行为)→ domain

    区分:PO是数据库映射;Domain实体是业务模型,二者不是同一个东西。

四、核心概念

  1. 充血模型 vs 失血模型
    • 失血:数据和行为分离,行为全部在Service;MVC默认写法。
    • 充血:业务行为放在实体/聚合内部,对象自己拥有业务能力;DDD追求的模型。
  2. 聚合 & 聚合根
    业务一致性边界;外部只能通过聚合根访问聚合内部对象,业务不变量在聚合内保证。
  3. 端口+适配器(六边形)
    domain定义抽象端口;infrastructure是适配器;想换数据库、换第三方,只改适配器,核心领域不动。
  4. 应用层(case)和领域层的边界
    • case:"做什么"(流程)
    • domain:"怎么做才符合业务规则"(规则)
      例:下单流程在case;订单金额校验、库存扣减规则、订单状态流转,放在domain。

五、改造示例(下单)

❌ MVC:Controller → OrderService(校验商品、扣库存、生成订单、调用支付、保存DB)→ DAO

✅ DDD六边形:

  1. trigger接收HTTP请求,参数校验
  2. trigger调用OrderCase(应用编排)
  3. OrderCase调度订单聚合、库存聚合
  4. Order聚合、Inventory聚合内部实现业务规则
  5. domain定义仓储接口
  6. infrastructure的仓储实现,操作MySQL、调用第三方RPC

六、常见误区

  1. ❌ 直接把Service包名改成domain,逻辑不动 → 伪DDD
  2. ❌ 在domain里面直接注入Mapper、操作数据库 → 破坏依赖方向
  3. ❌ case层写业务规则、判断校验 → 职责越界
  4. ❌ 认为DDD替代MVC:二者可以共存;DDD是业务建模和架构组织方式,MVC是入口层的模式。

七、适用场景

  • ✅ 适合:业务复杂、业务规则经常变更、长期迭代、需要频繁替换外部依赖的系统(交易、订单、会员、风控)
  • ❌ 不适合:简单CRUD、报表、简单后台,强行DDD会增加开发成本

八、面试一句话总结

MVC是横向按技术切分 ,DDD六边形是以领域为中心,纵向按业务能力切分;MVC的Service是大杂烩,DDD把它拆成应用编排、领域规则、基础设施三块,保证业务核心和外部技术解耦。

相关推荐
paopaokaka_luck1 小时前
灾害应急物资管理系统(AI应急助手、Echarts可视化数据看板、捐赠入库联动、 物资全流程管理、库存变动追溯、灾情资讯与互动反馈、物资发放公示)
java·前端·javascript·spring boot·mysql·tomcat·echarts
方方洛1 小时前
ray教程-23-附录C-术语表
人工智能·分布式·机器学习
SL_staff1 小时前
HR系统对接钉钉考勤总失败?根源在于缺乏业务语义级逻辑中枢
java·开源·全栈
程序边界1 小时前
一台数据集成软件的拆解笔记(下):一致性、容错、跑批与迁移,KFS 真正难的地方在这
java·前端·笔记
揣一尾游鱼yu2 小时前
内部类和Object笔记
java·开发语言·object·内部类
你怎么知道我是队长2 小时前
C++零基础第3周:if/else、switch、for/while/do-while 控制流完全指南(附20段可运行代码+避坑清单)
java·开发语言·c++
damoluomu3 小时前
Node 的 Headless 出厂没有前台,Java 的 Headless 是从门户里长出来的
java·开发语言·node.js
我命由我123453 小时前
Python 实用操作 - 文件操作(打开与关闭文件、读取文件、文件写入)
java·开发语言·前端·javascript·数据库·python·java-ee
学长毕设4 小时前
基于SpringBoot的网上流浪狗救助捐赠平台-附源码
java·spring boot·后端