第46篇-DDD战略设计-领域建模
【Kotlin Spring Boot 4 从零到架构师】第 46 篇DDD 战略设计 — 领域建模本系列定位零基础入门从 Kotlin 语法一路到 Spring Boot 4 高级架构DDD Modulith适合 Java 开发者转型也适合纯新手系统学习。本篇你将学到DDD领域驱动设计的核心思想与价值战略设计领域、子域、限界上下文统一语言Ubiquitous Language实体、值对象、聚合根的区别领域事件的概念学完本篇你将理解 DDD 不是一种代码技术而是一种用业务语言驱动软件设计的方法论。一、为什么需要 DDD1.1 传统开发的困境业务人员说用户下单后先扣库存再生成订单。 开发人员写的代码UserOrderService.createOrder() 问题 - 业务和技术说不同的语言沟通成本高 - 业务逻辑散落在 Service / Controller / Repository 中 - 随着业务增长代码变成「大泥球」1.2 DDD 的核心主张软件的核心价值 对业务领域的准确建模 不是「数据库驱动设计」先建表再写代码 而是「领域驱动设计」先理解业务再建模型最后落地到代码和数据库二、战略设计2.1 领域与子域领域Domain整个业务系统覆盖的范围。mini-shop 的领域 电商系统。子域Subdomain把大领域拆分成可管理的小块。电商领域 ├── 商品子域核心 ← 商品管理、库存、搜索 ├── 订单子域核心 ← 下单、支付、发货 ├── 用户子域支撑 ← 注册、登录、个人信息 ├── 通知子域通用 ← 邮件、短信 └── 统计子域通用 ← 报表、分析子域类型特点示例核心子域业务核心竞争力最值得投入商品、订单支撑子域必要但不是核心用户管理通用子域通用功能可用现成方案通知、日志下面用 Mermaid 图来直观展示电商领域的子域划分电商领域通用子域支撑子域核心子域通知子域商品子域订单子域用户子域统计子域2.2 限界上下文Bounded Context限界上下文是一个模型的边界——在这个边界内每个业务概念都有明确的、唯一的含义。商品这个词在不同上下文中含义不同 商品上下文Product Context Product { id, name, price, stock, category } 关注商品信息、库存 订单上下文Order Context OrderItem 中的 Product { productId, name, unitPrice } 关注购买时的快照名称和价格定格在购买那一刻 搜索上下文Search Context ProductDocument { id, name, category, score } 关注搜索相关性每个限界上下文有独立的模型不需要共享同一套实体类。上下文之间通过接口或事件通信。2.3 上下文映射Context Map描述限界上下文之间的关系┌──────────────┐ API 调用 ┌──────────────┐ │ Order │ ──────────→ │ Product │ │ Context │ 查询商品信息 │ Context │ └──────────────┘ └──────────────┘ │ │ │ 发布事件 │ 发布事件 ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ Notification │ │ Search │ │ Context │ │ Context │ └──────────────┘ └──────────────┘下面用 Mermaid 图来更清晰地展示各限界上下文之间的映射关系搜索上下文通知上下文商品上下文订单上下文API 调用查询商品信息发布事件OrderCreated发布事件ProductUpdatedOrder ContextProduct ContextNotification ContextSearch Context2.4 统一语言团队开发 产品 业务共同约定的词汇表贯穿业务文档到代码命名统一语言代码中的体现商品ProductProduct类订单OrderOrder类下单Place OrderplaceOrder()方法扣减库存Deduct StockdeductStock()方法已发货ShippedOrderStatus.SHIPPED核心原则代码中的命名应该和业务人员使用的词汇一致。不要出现业务人员说「下单」而代码写createRecord()这种不一致。三、核心构造块3.1 实体Entity有唯一标识的对象。即使属性完全相同ID 不同就是不同的实体。// Order 是实体——即使两个订单的金额、商品完全相同只要 ID 不同就是不同的订单classOrder(valid:Long,varstatus:OrderStatus,vartotalAmount:BigDecimal,valitems:ListOrderItem)特征有唯一标识ID可变属性可以修改生命周期内标识不变3.2 值对象Value Object没有唯一标识的对象完全由属性值定义。属性值相同的两个值对象是等价的。// Address 是值对象——两个地址相同的 Address 是等价的dataclassAddress(valprovince:String,valcity:String,valstreet:String,valzipCode:String)// Money 是值对象dataclassMoney(valamount:BigDecimal,valcurrency:String){operatorfunplus(other:Money):Money{require(currencyother.currency)returnMoney(amountother.amount,currency)}}特征没有标识靠属性值区分不可变val两个值相同的值对象可以互相替换Kotlin 的data class天然适合做值对象——自动生成equals/hashCode。3.3 聚合与聚合根Aggregate Root**聚合Aggregate**是一组相关对象的集合它们被视为一个整体进行数据修改。聚合根是聚合的入口点——外部只能通过聚合根操作聚合内的对象。Order 聚合 ┌───────────────────────────────────────┐ │ Order聚合根 │ │ ├── id: Long │ │ ├── status: OrderStatus │ │ ├── shippingAddress: Address值对象 │ │ ├── items: ListOrderItem │ │ │ ├── productId │ │ │ ├── quantity │ │ │ └── unitPrice │ │ └── totalAmount: Money值对象 │ └───────────────────────────────────────┘ 外部代码只能通过 Order 操作 items ✅ order.changeItemQuantity(productId, 5) ← 通过聚合根 ❌ orderItem.setQuantity(5) ← 绕过聚合根破坏封装聚合设计原则尽可能小的聚合只包含必须一起修改的对象通过 ID 引用其他聚合不要直接持有对象引用只持有 ID一个事务只修改一个聚合保证一致性下面用 Mermaid 图来直观展示 Order 聚合的结构containshashashas1111*111OrderLong idOrderStatus statusAddress shippingAddressListOrderItem itemsMoney totalAmountchangeItemQuantity(productId, quantity)OrderItemLong productIdint quantityMoney unitPriceAddressString provinceString cityString streetString zipCodeMoneyBigDecimal amountString currencyplus(other)3.4 领域事件Domain Event领域中发生的、业务关心的事件。// 订单已创建事件dataclassOrderCreatedEvent(valorderId:Long,valuserId:Long,valtotalAmount:BigDecimal,valoccurredAt:LocalDateTimeLocalDateTime.now())// 订单已支付事件dataclassOrderPaidEvent(valorderId:Long,valoccurredAt:LocalDateTimeLocalDateTime.now())事件是已发生的事实用过去式命名。其他模块可以订阅这些事件并做出反应。3.5 各构造块对比构造块标识可变性示例实体有唯一 ID可变Order、Product、User值对象无靠值区分不可变Address、Money聚合根有唯一 ID可变Order聚合的入口领域事件有事件 ID不可变OrderCreatedEvent四、mini-shop 领域模型分析4.1 识别限界上下文mini-shop 分为 4 个限界上下文 1. Product商品上下文 - 聚合根Product - 值对象Price - 实体ProductCategory 2. Order订单上下文 - 聚合根Order - 实体OrderItem - 值对象ShippingAddress、Money - 领域事件OrderCreated、OrderPaid、OrderShipped 3. User用户上下文 - 聚合根User - 值对象Email、PhoneNumber 4. Notification通知上下文 - 订阅 Order 上下文的事件 - 发送邮件/短信4.2 识别聚合Product 聚合 根Product 内部无子实体Price 是值对象 Order 聚合 根Order 内部OrderItem实体、ShippingAddress值对象 引用userId引用 User 聚合但不持有 User 对象 productId引用 Product 聚合只持有 ID4.3 统一语言词汇表中文 英文 类型 上下文 商品 Product 实体 Product 价格 Price 值对象 Product / Order 订单 Order 聚合根 Order 订单明细 OrderItem 实体 Order 收货地址 ShippingAddress 值对象 Order 下单 placeOrder 操作 Order 取消订单 cancelOrder 操作 Order 已发货 SHIPPED 状态 Order 库存不足 OutOfStock 异常 Product本篇小结知识点核心内容DDD领域驱动设计——业务驱动软件设计子域核心竞争力、支撑必要、通用现成方案限界上下文模型边界每个概念在边界内有唯一含义统一语言业务词汇贯穿到代码实体有唯一 ID可变值对象无 ID靠值区分不可变聚合根聚合的入口外部只能通过它操作领域事件已发生的事实用过去式命名聚合设计原则小聚合、ID 引用、一事务一聚合下篇预告第 47 篇DDD 战术设计 — 代码落地理论明白了代码怎么写下一篇把 DDD 概念落地为 Kotlin 代码分层架构、聚合根实现、Repository 模式、应用服务。如果本篇内容对你有帮助欢迎点赞收藏有任何疑问欢迎在评论区交流。

相关新闻

Python动态数据爬取实战:从API请求到无头浏览器渲染

Python动态数据爬取实战:从API请求到无头浏览器渲染

1. 项目概述:为什么动态数据爬取是爬虫工程师的必修课如果你用Python写过爬虫,大概率遇到过这种情况:用requests库配合BeautifulSoup,信心满满地写好了代码,结果运行后只抓回来一个空荡荡的HTML骨架,或者寥…

2026/10/17 23:57:25 阅读更多 →
使用Ink和React构建交互式命令行界面:从console.log到现代TUI的升级实践

使用Ink和React构建交互式命令行界面:从console.log到现代TUI的升级实践

1. 项目概述:从单调日志到交互式终端 如果你和我一样,长期在终端里敲打命令、查看日志,那你一定对满屏的 console.log 感到审美疲劳。那种白底黑字、毫无层次感的输出,不仅信息密度低,在排查复杂流程时,眼…

2026/10/16 10:50:04 阅读更多 →
深入解析PN结:从半导体基础到二极管特性与应用

深入解析PN结:从半导体基础到二极管特性与应用

1. 项目概述:从“半导体”到“PN结”的跨越 刚接触模拟电路,很多人会卡在第一个真正的“拦路虎”——PN结。翻开教材,满篇的“载流子”、“扩散运动”、“空间电荷区”,看得人云里雾里,感觉和之前学的电路基础完全是两…

2026/10/16 2:14:10 阅读更多 →

最新新闻

CH341A+NeoProgrammer刷BIOS:救砖、备份与排错指南

CH341A+NeoProgrammer刷BIOS:救砖、备份与排错指南

简介:CH341A编程器工具整合包,面向电子维修工程师、嵌入式开发者和硬件爱好者,用于对Flash、EEPROM及各类微控制器开展固件读写、芯片备份与故障恢复,是主板BIOS烧录、路由器刷机等实操场景的常用工具。资源共71个文件&#xff0c…

2026/10/19 0:53:08 阅读更多 →
Selenium元素底层逻辑:属性、定位、等待与异常排查全解析

Selenium元素底层逻辑:属性、定位、等待与异常排查全解析

刚开始接触Web自动化的人,大概率都会在“元素”这两个字上卡住很久。明明照着教程写了driver.find_element(By.ID, "login"),也明明在浏览器里看到了那个输入框,可代码一跑就是报错;或者定位到了,点下去却没…

2026/10/19 0:53:08 阅读更多 →
diagram-design:用代码思维管理图表,提升可维护性与一致性

diagram-design:用代码思维管理图表,提升可维护性与一致性

1. 从一张草图到一套系统:diagram-design 到底在解决什么问题很多人第一次听到 diagram-design 这个词,会下意识觉得它只是“画图”的另一种说法。但真正在项目里被图表折磨过的人知道,画图本身从来不是难点,难点在于图表的可维护…

2026/10/19 0:53:08 阅读更多 →
QPSK调制下DFE-RLS信道均衡的误码率仿真分析与MATLAB实现

QPSK调制下DFE-RLS信道均衡的误码率仿真分析与MATLAB实现

简介:一份面向无线通信学习与研究者的 MATLAB 仿真程序,围绕 QPSK 调制在两种不同信道环境下的误码性能展开分析。程序结合判决反馈均衡器(DFE)与递归最小二乘(RLS)算法,可用于分析多径信道引起…

2026/10/19 0:53:08 阅读更多 →
ASP.NET MVC工作流管理系统源码解析:流程引擎与表单设计器实战

ASP.NET MVC工作流管理系统源码解析:流程引擎与表单设计器实战

简介:这是一套基于ASP.NET MVC5开发的工作流管理系统源码,内置可视化流程设计器与表单设计器,适合正在从事OA办公、CRM客户关系或HR人事管理系统的开发者参考学习,也可作为掌握MVC架构与工作流引擎原理的实战范例。压缩包共约2000…

2026/10/19 0:52:08 阅读更多 →
Rocky Linux 8.5部署Jenkins:跨平台CI/CD与容器化构建实战

Rocky Linux 8.5部署Jenkins:跨平台CI/CD与容器化构建实战

在Rocky Linux 8.5上部署Jenkins,这件事听起来不算新鲜,但真要把流水线做到能支撑跨平台CI/CD、还能把容器化构建跑得又快又稳,很多人是踩了坑才回头补课的。我这套方案是在某制造企业的研发基础设施改造中一步步磨出来的,前后在虚…

2026/10/19 0:52:08 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →