大家好,我是小米,一个热爱技术、喜欢分享的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)
聚合 是领域对象的组合体,体现整体与部分的关系。它的主要特点是:
- 聚合内有一个根实体,称为 聚合根(Aggregate Root)。
- 聚合根负责管理聚合内部对象的生命周期。
- 只能通过聚合根访问和操作内部对象。
示例:在订单聚合中,订单是聚合根,订单项(OrderItem)是其组成部分。
判断是否是聚合关系:如果聚合根不存在,内部对象也应该失去意义。
工厂与仓库
工厂(Factory)
工厂负责创建复杂的领域对象,是领域对象生命周期的起点。
示例:订单工厂创建订单。
仓库(Repository)
仓库是领域模型与数据存储的桥梁,负责领域对象的持久化和检索。
示例:订单仓库。
总结
领域驱动设计提供了一套完整的理论体系,帮助我们应对复杂业务系统的开发。
关键点如下:
- 领域和子域:明确系统边界,按业务模块划分。
- 限界上下文:定义领域模型的边界,与微服务对应。
- 领域对象:实体与值对象结合,贫血与充血模式各有应用场景。
- 聚合:体现整体与部分的关系,聚合根统一管理。
- 工厂与仓库:分别负责对象的创建和持久化。
END
希望这篇文章能让你对领域模型有更清晰的理解!如果你喜欢,记得转发和点赞哦~
我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!