Java DDD(领域驱动设计)
一句话核心DDD领域驱动设计不是一套框架而是一种代码组织哲学。它要求你用代码直接翻译业务语言而不是把业务逻辑散落在增删改查CRUD里。对于Java开发者最经典的DDD范式就是**“四层架构” “六大战术模式”。为了让你秒懂我们把项目类比为“一家餐厅”**表现层Controller 服务员接收顾客指令。应用层Application 大堂经理调度任务发号施令。领域层Domain 厨师长 菜谱核心资产业务规则所在。基础设施层Infrastructure 冰箱、灶台数据库、Redis、MQ。下面我直接给你展示标准的Java DDD包结构和核心代码范式一看就懂。1. 标准的Java DDD包结构范式骨架com.example.order/ ├── interfaces/ # 表现层处理HTTP/RPC │ └── OrderController.java ├── application/ # 应用层用例编排无业务逻辑 │ ├── service/ # 应用服务如OrderApplicationService │ └── dto/ # 数据传输对象Request/Response ├── domain/ # 领域层核心只依赖Java本身不依赖Spring/DB │ ├── model/ # 领域模型 │ │ ├── aggregate/ # 聚合根如Order │ │ ├── entity/ # 实体如OrderItem │ │ └── vo/ # 值对象如Address, Money │ ├── service/ # 领域服务处理跨多个实体的复杂业务 │ └── repository/ # 仓储接口定义“我需要什么数据”不实现 └── infrastructure/ # 基础设施层实现Domain层的接口 ├── repository/ # 仓储实现JPA/MyBatis └── config/ # 配置类2. 六大战术模式Java代码实战为了便于理解我们模拟一个**“下单”**场景必须验证地址且订单总价要打折。① 值对象 (Value Object) —— 用record或不可变类特点没有唯一ID通过属性值判断相等性。封装业务规则。// 值对象地址publicrecordAddress(Stringprovince,Stringcity,Stringdetail){publicAddress{// 业务规则地址不能为空直接写在构造方法里if(provincenull||citynull){thrownewIllegalArgumentException(省市必填);}}}// 值对象金额publicclassMoney{privatefinalBigDecimalamount;privatefinalStringcurrency;// 通常用枚举// 封装加法逻辑而不是在Service里用BigDecimal算publicMoneyadd(Moneyother){...}}② 实体 (Entity) —— 有唯一ID可变Entity// 注意这里的注解是JPA的但DDD要求Domain层纯POJO所以通常把这个类放在infrastructure层做映射或者在Domain层不加Table注解。publicclassOrderItem{privateLongitemId;// 唯一标识privateStringproductName;privateIntegerquantity;privateMoneyprice;// 引用值对象}③ 聚合根 (Aggregate Root) ——DDD最重要的范式聚合根是外部访问聚合的唯一入口。比如“订单(Order)”和“订单项(OrderItem)”是整体外部只能操作Order不能直接修改OrderItem。// 领域层 - 聚合根publicclassOrder{privateLongorderId;// 唯一标识privateAddressshipAddress;// 值对象privateListOrderItemitems;// 实体集合privateOrderStatusstatus;// 核心业务方法充血模型业务逻辑写在实体内部而不是Service里publicvoidplaceOrder(){// 规则1下单必须校验地址封装在领域内部if(this.shipAddressnull){thrownewBusinessException(缺少收货地址);}// 规则2计算总价并打折满100减10MoneytotalcalculateTotal();if(total.amount().compareTo(newBigDecimal(100))0){// 打折逻辑...}this.statusOrderStatus.PLACED;// 发布领域事件可选DomainEventPublisher.publish(newOrderPlacedEvent(this.orderId));}// 计算总价也不允许Service插手由实体自己算privateMoneycalculateTotal(){returnitems.stream().map(OrderItem::getPrice).reduce(Money::add).orElse(...);}}④ 仓储接口 (Repository) ——依赖倒置的核心Domain层定义“我要什么”Infrastructure层实现“怎么拿”。// domain/repository/OrderRepository.java (接口)publicinterfaceOrderRepository{OrderfindById(Longid);voidsave(Orderorder);// 传入聚合根整个聚合一起保存}// infrastructure/repository/OrderRepositoryImpl.java (实现)RepositorypublicclassOrderRepositoryImplimplementsOrderRepository{AutowiredprivateOrderJpaMappermapper;// MyBatis或JPAOverridepublicvoidsave(Orderorder){// 1. 保存Order主表// 2. 保存OrderItem子表全部替换策略// 领域层不知道底层是MySQL还是Redis}}⑤ 领域服务 (Domain Service)当业务逻辑不属于某个具体的实体时使用比如转账涉及两个账户。// domain/service/TransferService.javapublicclassTransferService{publicvoidtransfer(Accountfrom,Accountto,Moneyamount){from.debit(amount);// 实体自己的方法to.credit(amount);}}⑥ 应用层 (Application Service) ——极薄的一层只做三件事拿数据、调领域方法、存数据。绝对不写 if-else 业务判断。// application/service/OrderAppService.javaServiceTransactionalpublicclassOrderAppService{privatefinalOrderRepositoryorderRepository;// 用例用户下单publicLongplaceOrder(PlaceOrderCommandcmd){// 1. 从仓储拿聚合根如果是新建则newOrderordernewOrder();// 2. 调用领域方法业务逻辑进入领域层order.placeOrder();// 3. 仓储保存orderRepository.save(order);// 4. 返回结果returnorder.getOrderId();}}3. 必须遵守的“铁律”DDD Java范式红线层级是否允许依赖Spring注解是否允许依赖数据库职责领域层 (Domain)❌ 禁止纯Java POJO❌ 禁止只写interface定义规则写业务逻辑方法应用层 (Application)✅ 允许 (Service)❌ 禁止编排用例调用领域方法事务发起点基础设施层 (Infra)✅ 允许 (Repository)✅ 允许实现接口处理SQL、Redis、MQ表现层 (Interfaces)✅ 允许 (RestController)❌ 禁止参数校验、返回JSON为什么领域层禁止用Spring注解因为DDD追求**“业务逻辑与技术解耦”**。如果Autowired进了Domain换用Quarkus或单元测试时就废了。Domain应该是可以脱离Spring直接用new Order().placeOrder()就能跑单元测试的。4. 贫血模型 vs 充血模型一眼辨别真假DDD传统CRUD贫血Order类只有getter/setter所有if/else全在OrderServiceImpl里。→这是假DDD。DDD范式充血Order类拥有placeOrder()、cancel()、calculateTotal()方法。OrderAppService只有寥寥几行调用。→这是真DDD。总结记住这张脑图表现层接收请求 →应用层从基础设施层拿到仓储接口的实现 → 交给领域层的聚合根执行业务方法内部包含实体和值对象的规则 → 应用层再通过仓储存回去。如果只是简单的增删改查请不要用DDD杀鸡用牛刀。但如果业务逻辑极其复杂如电商、金融、医疗这个Java范式就是防止代码腐烂的最强武器。记住核心口诀“让代码说业务的话让数据库滚去基础设施层”。

相关新闻

MSPM0微控制器NONMAIN配置详解:从安全启动到量产避坑指南

MSPM0微控制器NONMAIN配置详解:从安全启动到量产避坑指南

1. 项目概述:为什么你需要关注MSPM0的NONMAIN配置?如果你正在使用德州仪器(TI)的MSPM0 L系列微控制器,并且你的产品即将进入量产阶段,或者你正在设计一个对安全性、可靠性和知识产权保护有要求的嵌入式系统…

2026/7/24 1:08:20阅读更多 →
TVP5146M2 VBI数据处理实战:从寄存器配置到CC字幕与WSS信令提取

TVP5146M2 VBI数据处理实战:从寄存器配置到CC字幕与WSS信令提取

1. TVP5146M2:不只是解码,更是视频信息的“翻译官”在数字视频处理的世界里,解码器常常被简单地看作一个“翻译”,负责将模拟的CVBS、S-Video或分量信号转换成数字世界能理解的YUV或RGB数据流。然而,如果你只把TVP5146…

2026/7/24 1:08:20阅读更多 →
基于BERT的中文文本情感分类实战指南

基于BERT的中文文本情感分类实战指南

1. 项目概述中文文本情感分类是自然语言处理领域的基础任务之一,其目标是将给定的中文文本划分为积极、消极或中性等情感类别。随着预训练语言模型的兴起,基于BERT的文本分类方法已成为当前主流技术路线。本文将全面解析如何利用BERT预训练模型构建中文情…

2026/7/24 1:06:20阅读更多 →
嵌入式系统硬件事件驱动架构:MSPM0事件管理器原理与实战

嵌入式系统硬件事件驱动架构:MSPM0事件管理器原理与实战

1. 项目概述:为什么嵌入式系统需要事件管理器?在嵌入式开发里,尤其是做实时性要求高的项目,比如电机控制、传感器数据采集或者通信协议栈,我们经常会遇到一个核心矛盾:如何让硬件模块之间高效、及时地“对话…

2026/7/24 2:46:36阅读更多 →
深入解析MSPM0 GPIO与IOMUX:从引脚配置到低功耗系统设计

深入解析MSPM0 GPIO与IOMUX:从引脚配置到低功耗系统设计

1. 从引脚到系统:理解MSPM0的GPIO与IOMUX架构在嵌入式开发中,GPIO(通用输入输出)和IOMUX(输入输出复用器)是连接微控制器内部逻辑与外部物理世界的桥梁。对于TI的MSPM0系列微控制器,这两个模块的…

2026/7/24 2:46:36阅读更多 →
从curl到工程封装:ICP备案查询

从curl到工程封装:ICP备案查询

应用场景:何时需要自动化查询ICP备案 在日常开发或运维中,以下场景会频繁用到ICP备案查询接口: 域名合规审核:在用户提交域名绑定、域名接入时,自动检测域名是否已备案,未备案则拒绝或提醒。备案状态监控…

2026/7/24 2:46:36阅读更多 →
CHI 与 NVSwitch 的协议理论分析(否定)

CHI 与 NVSwitch 的协议理论分析(否定)

一、核心定位对比维度ARM CHI (Coherent Hub Interface)NVIDIA NVSwitch设计目标通用片上/片间缓存一致性互联协议GPU 专用 Scale-Up 交换芯片一致性模型全缓存一致性(MESI/MOESI)内存一致性访问(非严格缓存一致性)路由机制基于 H…

2026/7/24 2:46:36阅读更多 →
信创模盒亮相WAIC 2026:国产算力适配的“重要引擎”引发政企关注

信创模盒亮相WAIC 2026:国产算力适配的“重要引擎”引发政企关注

▎直击国产算力核心痛点,信创模盒交出硬核答卷本届大会最值得记录的图景,是模型与芯片两个阵营的历史性同台。模型一侧在"向上摸高"。261款大模型参展,国产开源阵营集体迈向3T参数量级:月之暗面Kimi K3以2.8万亿参数成为…

2026/7/24 2:46:36阅读更多 →
自动化发现框架选型:为何不存在万能钥匙及实践指南

自动化发现框架选型:为何不存在万能钥匙及实践指南

上周,一位做自动化测试的朋友在群里发了个截图,是他用某个新框架跑批量任务的结果:单条测试用例执行得飞快,但一到并发场景就各种超时和资源冲突。他问:“不是说这个框架能自动发现最优执行路径吗?为什么实…

2026/7/24 2:44:36阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 0:58:53阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 0:58:53阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 0:58:53阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:06阅读更多 →
【LeetCode 54】螺旋矩阵

【LeetCode 54】螺旋矩阵

问题描述: 解法: 1、模拟(参考自【LeetCode 54】螺旋矩阵-CSDN博客) int *spiralOrder(int **matrix, int matrixSize, int *matrixColSize, int *returnSize) {static const int dirs[4][2] {{0, 1}, {1, 0}, {0, -1}, {-1, …

2026/7/24 0:00:06阅读更多 →
2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

2026 WAIC:模型隐身、智能体疯野,厂商竞赛聚焦办公场景与商业闭环

知春路不相信模型领先今年WAIC大会,昔日AI六小龙来了五家,分别是Kimi、阶跃星辰、Minimax、百川智能、零一万物。连放弃基模的百川和零一万物都来了,唯一缺席的竟是近几个月来风光无限的智谱。(DeepSeek一直不参加)WAI…

2026/7/24 0:00:06阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/23 22:58:43阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/23 18:58:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/23 18:58:18阅读更多 →