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

软件求生 2024-11-22 10:12:10



大家好,我是小米,一个热爱技术、喜欢分享的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岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!

0 阅读:1
软件求生

软件求生

从事软件开发,分享“技术”、“运营”、“产品”等。