DDD学习笔记
DDD学习笔记
1. 什么是 DDD?
领域驱动设计(Domain-Driven Design, DDD)是一种复杂软件系统设计的方法,强调以业务领域为核心进行设计与开发。它通过将业务逻辑与代码组织紧密结合,帮助开发团队更好地理解和实现业务需求。
2. DDD 核心概念
2.1 领域(Domain)
- 定义:指应用程序的业务逻辑所在的范围,反映了现实世界中的问题空间。
- 意义:领域定义了软件系统的边界,帮助我们理解业务需求。
2.2 子域(Subdomain)
- 定义:将领域划分为更小的、具有独立功能的部分。
- 类型:核心子域(Core Subdomain)、支撑子域(Supporting Subdomain)、通用子域(Generic Subdomain)。
2.3 通用语言(Ubiquitous Language)
- 定义:开发团队与业务专家共享的语言,用于描述领域中的概念与行为。
- 重要性:减少误解,促进开发团队和业务方的交流。
2.4 聚合(Aggregate)
- 定义:一个或多个对象的集合,视为一个单元,共同维护业务逻辑和数据一致性。
- 聚合根(Aggregate Root):聚合中的主对象,负责与外界交互并控制聚合内的其他对象。
2.5 实体(Entity)
- 定义:具有唯一标识的对象,其生命周期和状态会随着时间变化。
- 示例:用户、订单等。
2.6 值对象(Value Object)
- 定义:没有唯一标识,仅根据其属性定义,通常不可变。
- 示例:货币金额、坐标等。
2.7 仓储(Repository)
- 定义:用于持久化聚合,模拟集合接口,为应用层提供获取和保存聚合的能力。
- 常见操作:添加、查找、删除等。
2.8 工厂(Factory)
- 定义:用于创建复杂对象或聚合,确保创建逻辑封装在统一的位置,避免对象构造的复杂性。
3. DDD 分层架构
领域驱动设计将系统分为多个层次,以便更好地组织代码,清晰分离不同职责。这种分层架构通常包括用户界面层、应用层、领域层和基础设施层,每一层都承担特定的功能。
3.1 用户界面层(User Interface Layer)
- 功能:负责处理用户与系统的交互,将用户的输入请求转发到应用层,并将应用层的结果显示给用户。这一层可以包括图形用户界面(GUI)、命令行界面(CLI)、API 或者其他外部接口。
- 职责:
- 将用户输入转换为系统可以理解的命令,并传递给应用层。
- 捕获应用层的响应,将其转化为用户可以理解的信息。
- 示例:在一个电商系统中,用户界面层可以是一个网页或移动应用,用户可以通过它来搜索商品、添加商品到购物车或下订单。
3.2 应用层(Application Layer)
- 功能:协调领域对象以完成特定的业务任务。应用层定义了系统的用例,并管理事务和安全等非功能性要求。需要注意的是,这一层不包含具体的业务逻辑,只负责调度领域层的操作。
- 职责:
- 定义应用程序的服务,如用户注册、订单提交等,确保业务流程的正确执行。
- 处理与用户界面层的交互,调用领域层的业务逻辑,并将结果返回给用户界面层。
- 控制事务边界,确保操作的原子性和一致性。
- 示例:在一个银行系统中,应用层的一个服务可能是“转账服务”,它会协调账户的取款和存款操作,确保整个转账过程是一个完整的事务。
3.3 领域层(Domain Layer)
- 功能:是整个系统的核心,包含所有业务逻辑和业务规则。领域层负责实现领域模型,包括实体、值对象、聚合、领域事件和领域服务等。这个层次是系统的关键,直接映射业务需求和领域概念。
- 组成:
- 实体(Entity):具有唯一标识的对象,其生命周期和状态会发生变化。比如,在一个人力资源管理系统中,
Employee
是一个实体,具有唯一的employee_id
和可变的属性,如name
、position
等。 - 值对象(Value Object):不具有唯一标识,仅通过属性定义对象的身份,通常是不可变的。比如,在一个地图应用中,
Coordinate
(坐标)可以是一个值对象,包含latitude
(纬度)和longitude
(经度)。 - 聚合(Aggregate):是一组相关对象的集合,由一个聚合根(Aggregate Root)控制。聚合根负责与外部系统交互,并维护聚合内的数据一致性。例如,在一个电商系统中,
Order
可以是一个聚合根,负责管理订单中的所有OrderItem
。 - 领域服务(Domain Service):当业务逻辑不属于单个实体或值对象时,使用领域服务来实现。比如,
PaymentService
可以是一个领域服务,负责处理支付逻辑。
- 实体(Entity):具有唯一标识的对象,其生命周期和状态会发生变化。比如,在一个人力资源管理系统中,
- 职责:
- 实现所有核心业务逻辑。
- 使用通用语言(Ubiquitous Language)建模领域对象和行为,以便开发团队和业务人员能达成一致理解。
- 示例:在一个订单管理系统中,领域层可能包含
Order
实体、OrderItem
值对象,以及一个计算订单总价的领域服务OrderPricingService
。
3.4 基础设施层(Infrastructure Layer)
- 功能:提供所有技术实现细节,为应用层和领域层提供支持。这包括数据库访问、消息传递、外部服务集成等。基础设施层可以使用各种框架和库来实现其功能,确保系统的持久性和可扩展性。
- 职责:
- 实现持久化机制,将领域对象保存到数据库或其他存储介质中。
- 提供对外部系统的集成,如邮件服务、支付网关、第三方 API 等。
- 处理系统的技术性需求,如日志记录、监控和消息队列等。
- 示例:在一个社交网络系统中,基础设施层可能会使用一个关系型数据库来存储用户信息,使用 Redis 实现缓存功能,并使用第三方服务发送电子邮件。
分层架构总结
DDD 分层架构通过清晰的职责划分,确保系统的可维护性和可扩展性。用户界面层专注于用户交互,应用层管理业务流程,领域层负责核心业务逻辑,而基础设施层提供技术支持。这种架构有助于团队在开发过程中明确各部分的职责,从而提高开发效率和系统的稳定性。
4. DDD 设计模式
4.1 领域服务(Domain Service)
- 用途:当业务逻辑不能很好地归属到某个实体或值对象时,使用领域服务来实现。
- 示例:支付处理、商品库存检查等。
4.2 应用服务(Application Service)
- 用途:协调领域对象和领域服务,执行应用逻辑,不包含复杂的业务规则。
- 职责:控制事务边界、处理用户请求、调用领域对象。
4.3 事件(Event)
- 定义:在系统中发生的业务事件,通常用于实现事件驱动架构和解耦组件之间的依赖。
- 示例:订单已创建、用户已注册等。
5. 实战总结
5.1 识别核心领域
- 方法:与业务方紧密合作,明确系统中的核心业务逻辑和支撑逻辑,将资源集中在核心领域。
5.2 建立通用语言
- 实践:确保团队成员(包括业务专家和开发人员)都使用一致的语言描述领域概念和业务流程。
5.3 设计聚合和实体
- 关键点:聚合根要确保数据一致性,值对象应保持不可变。
6. DDD 与 MVC 的区别
对比维度 | DDD(领域驱动设计) | MVC(模型-视图-控制器) |
---|---|---|
关注点 | 以复杂业务逻辑的建模和实现为核心,强调业务领域与系统设计的结合 | 以用户界面和数据交互的分离为核心,简化用户界面的开发与维护 |
设计目标 | 解决复杂业务系统中的设计难题,确保业务逻辑清晰和代码可维护性 | 提供简洁的界面开发结构,将视图与逻辑分离,便于快速实现和维护 |
架构层次 | 四层架构:用户界面层、应用层、领域层、基础设施层,领域层是核心 | 三层架构:模型、视图、控制器,结构简单,关注界面交互 |
业务逻辑处理 | 使用实体、值对象、聚合和领域服务封装复杂业务逻辑,保持逻辑一致性和完整性 | 业务逻辑通常在模型层中实现,适合简单逻辑,但易造成模型层膨胀 |
应用场景 | 适合复杂业务系统,如银行、ERP、供应链管理等,强调长期可维护性 | 适合用户界面驱动的系统,如网页应用、CRUD 应用,适合快速开发 |
复杂性 | 高复杂性,学习曲线陡峭,需深入理解业务领域和 DDD 概念 | 低复杂性,学习和实现简单,适合初学者和轻量级项目 |
长期效益 | 代码结构清晰,易于应对业务变化,适合大型和长期维护的项目 | 快速开发和迭代,适合短期或中小型项目,但对复杂业务支持不足 |
下图为MVC框架的项目结构