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岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号软件求生,获取更多技术干货!

相关文章
|
7月前
|
领域建模
架构设计 DDD领域建模 核心概念
【1月更文挑战第6天】架构设计 DDD领域建模 核心概念
|
缓存 前端开发 中间件
DDD 领域驱动设计落地实践系列:工程结构分层设计
前面几篇文章中,笔者给大家阐述了 DDD 领域驱动设计的三大过程,重点围绕如何通过战略设计与战术设计进行 DDD 落地实践进行了详细的讨论,但是还没有涉及到工程层面的落地。实际上所有的这些架构理论到最后都是为了使得我们代码结构更加清晰,从而开发出 bug 少、扩展性强、逻辑清楚的应用。因此本文就是为了解决 DDD 领域驱动落地实践最后一公里问题,将我们分析出来的领域模型通过与工程结构的映射实现真正的落地。
DDD 领域驱动设计落地实践系列:工程结构分层设计
|
前端开发 测试技术 API
DDD领域驱动设计实战-分层架构及代码目录结构(上)
DDD领域驱动设计实战-分层架构及代码目录结构
1540 0
DDD领域驱动设计实战-分层架构及代码目录结构(上)
|
存储 自然语言处理 前端开发
领域驱动设计(DDD)-基础思想
一、序言     领域驱动设计是一种解决业务复杂性的设计思想,不是一种标准规则的解决方法。在领域驱动设计理念上,各路大侠的观点也是各有不同,能力有限、欢迎留言讨论。 二、领域驱动设计 DDD是什么 wiki释义:     领域驱动设计(英语:Domain-driven design,缩写 DDD)是一种通过将实现连接到持续进化的模型[1]来满足复杂
7552 0
|
存储 设计模式 缓存
DDD领域驱动设计实战-分层架构及代码目录结构(下)
DDD领域驱动设计实战-分层架构及代码目录结构
1705 0
DDD领域驱动设计实战-分层架构及代码目录结构(下)
|
2月前
|
存储 前端开发 API
DDD领域驱动设计实战-分层架构
DDD分层架构通过明确各层职责及交互规则,有效降低了层间依赖。其基本原则是每层仅与下方层耦合,分为严格和松散两种形式。架构演进包括传统四层架构与改良版四层架构,后者采用依赖反转设计原则优化基础设施层位置。各层职责分明:用户接口层处理显示与请求;应用层负责服务编排与组合;领域层实现业务逻辑;基础层提供技术基础服务。通过合理设计聚合与依赖关系,DDD支持微服务架构灵活演进,提升系统适应性和可维护性。
|
4月前
|
存储 消息中间件 JSON
|
前端开发 架构师 Java
领域驱动设计DDD从入门到代码实践
在本文中,作者将借鉴《实现领域驱动设计》的做法,介绍领域驱动设计的基本概念的同时,用一个虚拟的公司和一个虚拟的项目,把领域驱动设计进行落地实践。
13525 9
领域驱动设计DDD从入门到代码实践
|
消息中间件 架构师 搜索推荐
DDD领域驱动设计的概念解析
DDD领域驱动设计的概念解析
254 1
|
消息中间件 JavaScript 小程序
领域驱动设计(DDD)的几种典型架构介绍
领域驱动设计(DDD)的几种典型架构介绍

热门文章

最新文章