DDD新手入门:领域模型设计的七个核心概念

简介: 小米,29岁程序员,分享领域模型落地知识。文章解析领域、子域、限界上下文、领域对象、聚合、工厂与仓库等概念,助你理解领域驱动设计。



大家好,我是小米,一个热爱技术、喜欢分享的29岁程序员!今天我们来聊聊 领域模型落地 这个话题。在微服务架构、领域驱动设计(DDD)流行的今天,我们经常听到“限界上下文”“领域对象”“实体”“值对象”等术语。它们之间是什么关系?如何落地到实际项目中?别急,这篇文章帮你理清思路!

什么是领域和子域?

领域(Domain) 是问题的核心,是业务逻辑发生的地方。比如,一个电商系统中,“商品管理”、“订单管理”和“支付管理”可以算作三个不同的领域。

而 子域(Subdomain) 是领域的更小划分,它们针对具体业务场景提供解决方案。例如,“商品管理”领域下,可能有“库存子域”和“价格子域”。

领域驱动设计的目标:把业务复杂度与技术实现解耦。通过划分领域与子域,将业务逻辑拆解成可理解、可管理的模块。

在实际项目中,子域的识别尤为重要。通过上下文地图(Context Map),可以把系统内的各个领域及其交互关系可视化,指导我们进一步划分限界上下文。

限界上下文(Bounded Context)

限界上下文是领域驱动设计的核心概念之一。它定义了领域模型的边界,让每个模型的含义在边界内保持清晰、一致。

定义:限界上下文是一个业务领域中的逻辑边界。它是领域模型与代码实现的桥梁。

举个例子,假设我们在做一个订单管理系统。订单中的“状态”可能在不同上下文下含义不同:

  • 订单管理上下文:状态指订单的生命周期(已创建、已支付、已取消)。
  • 物流上下文:状态表示配送的过程(已打包、运输中、已签收)。

通过划分限界上下文,每个上下文可以独立建模,避免概念混淆。对应到代码中,这些上下文通常落地为一个微服务或一个模块。

领域对象

在限界上下文内部,模型通过 领域对象 来表达。领域对象是领域驱动设计的基本单位,分为三类:

  • 实体(Entity):有唯一标识的对象。
  • 值对象(Value Object):没有唯一标识,表达不变的特性。
  • 服务(Service):封装了无法归属实体或值对象的操作逻辑。

领域对象 vs. 贫血模型和充血模型

  • 贫血模型:只有数据(get/set方法),业务逻辑放在 Service 中。
  • 充血模型:数据和业务逻辑集中在领域对象内,符合面向对象设计思想。

下面我们详细介绍 实体 和 值对象。

实体与值对象

实体(Entity)

实体是有生命周期的、独一无二的领域对象。它的核心特性是:

  • 有唯一标识(ID)。
  • 状态可以改变(可变性)。

例子:订单(Order)是一个实体,因为每个订单都有唯一的 ID,且其状态(如已支付、已取消)可能变化。

值对象(Value Object)

值对象用来描述无状态的、不可变的事物。它们通常是“用于计算的参数”或“对象的属性”。

例子:订单的金额(Price)可以建模为一个值对象,因为金额只有数值上的意义,不需要唯一标识。

在设计中,尽量优先使用值对象,因为它们更简单、安全。

贫血模型与充血模型

这两个模型是领域驱动设计中常见的设计模式:

贫血模型

在贫血模型中,领域对象只有属性和简单的 get/set 方法,所有的业务逻辑都放在服务(Service)中。虽然实现简单,但容易导致:

  • 领域模型与业务逻辑脱节。
  • 对象的行为和状态分散,不利于维护。

示例:POJO(Plain Old Java Object)形式的订单实体。

充血模型

充血模型是面向对象的体现。领域对象除了保存状态外,还负责与自身状态相关的行为。

示例:充血模型的订单实体。

充血模型的优势在于逻辑内聚,但需要适度设计,避免过于复杂。

聚合(Aggregate)

聚合 是领域对象的组合体,体现整体与部分的关系。它的主要特点是:

  1. 聚合内有一个根实体,称为 聚合根(Aggregate Root)。
  2. 聚合根负责管理聚合内部对象的生命周期。
  3. 只能通过聚合根访问和操作内部对象。

示例:在订单聚合中,订单是聚合根,订单项(OrderItem)是其组成部分。

判断是否是聚合关系:如果聚合根不存在,内部对象也应该失去意义。

工厂与仓库

工厂(Factory)

工厂负责创建复杂的领域对象,是领域对象生命周期的起点。

示例:订单工厂创建订单。

仓库(Repository)

仓库是领域模型与数据存储的桥梁,负责领域对象的持久化和检索。

示例:订单仓库。

总结

领域驱动设计提供了一套完整的理论体系,帮助我们应对复杂业务系统的开发。

关键点如下:

  • 领域和子域:明确系统边界,按业务模块划分。
  • 限界上下文:定义领域模型的边界,与微服务对应。
  • 领域对象:实体与值对象结合,贫血与充血模式各有应用场景。
  • 聚合:体现整体与部分的关系,聚合根统一管理。
  • 工厂与仓库:分别负责对象的创建和持久化。

END

希望这篇文章能让你对领域模型有更清晰的理解!如果你喜欢,记得转发和点赞哦~

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!

相关文章
|
存储 自然语言处理 前端开发
领域驱动设计(DDD)-基础思想
一、序言     领域驱动设计是一种解决业务复杂性的设计思想,不是一种标准规则的解决方法。在领域驱动设计理念上,各路大侠的观点也是各有不同,能力有限、欢迎留言讨论。 二、领域驱动设计 DDD是什么 wiki释义:     领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂
8968 0
|
微服务 测试技术 Java
阿里技术专家详解 DDD 系列- Domain Primitive
关于DDD的一系列文章,希望能继续在总结前人的基础上发扬光大DDD的思想,但是通过一套我认为合理的代码结构、框架和约束,来降低DDD的实践门槛,提升代码质量、可测试性、安全性、健壮性。
63598 17
阿里技术专家详解 DDD 系列- Domain Primitive
|
8月前
|
SQL Java 测试技术
告别 CRUD 泥沼!DDD 领域驱动设计:从底层原理到生产级全链路落地实战
DDD是应对复杂业务的架构思想,核心是“领域优先、边界隔离”:通过战略设计(统一语言、限界上下文、上下文映射)划清业务边界;通过战术设计(实体/值对象、聚合根、领域服务等)落地高内聚、低耦合的代码。非银弹,适用于规则多、迭代快、协作难的场景。
1906 1
|
11月前
|
数据采集 领域建模 数据库
领域模型图(数据架构/ER图)
本文介绍通过四色原型法构建领域模型并生成ER图的过程。运用MI(时标)、PPT(参与方-地点-物品)、Role(角色)和DESC(描述)四种原型,逐步抽象风控系统的业务流程,提炼实体与关系,最终形成数据架构中的ER图,为数据库设计提供基础支撑。(238字)
|
12月前
|
架构师 微服务
【架构师】微服务的拆分有哪些原则?
微服务拆分需遵循七大原则:职责单一、围绕业务、中台化公共模块、按系统保障级别分离、技术栈解耦、避免循环依赖,并遵循康威定律使架构与组织匹配,提升可维护性与协作效率。
719 4
|
6月前
|
人工智能 安全 开发工具
Claude Code 官方工作原理与使用指南
Claude Code 不是传统代码补全工具,而是 Anthropic 推出的终端 AI 代理,具备代理循环、双驱动架构(模型+工具)、全局项目感知、6 种权限模式等核心能力,本文基于官方文档系统解析其工作原理与高效使用技巧。
4206 0
|
人工智能 监控 安全
让Agent系统更聪明之前,先让它能被信任
当我们将所有希望寄托于大模型的「智能」时,却忘记了智能的不确定性必须以工程的确定性为支撑。一个无法复现、无法调试、无法观测的智能,更像是一场精彩但失控的魔法,而非我们真正需要的、可靠的生产力。本文尝试从系统工程的视角剖析 Agent 系统在可运行、可复现与可进化三个层次上不断升级的问题以及复杂度。进一步认识到:框架/平台让 Agent 「好搭」但没有让它「好用」,真正的复杂性,从未被消除,只是被推迟。
1441 33
让Agent系统更聪明之前,先让它能被信任
|
10月前
|
人工智能 自然语言处理 Java
Spring AI Alibaba实战:从0到1构建企业级智能应用
本文介绍了基于SpringAI Alibaba框架开发AI原生应用的实战指南。文章首先分析了SpringAI Alibaba作为SpringAI本土化版本的核心优势,包括深度适配阿里云生态、中文语境优化等特性。随后详细讲解了开发环境的搭建过程,包括JDK17、SpringBoot3.2.2等技术栈的配置。通过三个实战案例展示了核心功能实现:基础文本生成、结合MyBatisPlus的智能问答系统、以及流式响应和函数调用等高级特性。
6874 6
|
存储 设计模式 NoSQL
ddd领域驱动设计
领域驱动设计(DDD)是一种应对复杂软件系统的思维革命与系统方法。它通过“通用语言”统一团队认知,运用“限界上下文”划分业务边界,结合“聚合”“领域事件”等战术模式,精准构建业务模型。DDD不仅提升软件对业务的映射能力,更为微服务架构提供科学的边界划分依据,是打造高内聚、低耦合系统的核心方法论。