当前位置: 首页 > news >正文

DDD学习笔记

DDD学习笔记

1. 什么是 DDD?

领域驱动设计(Domain-Driven Design, DDD)是一种复杂软件系统设计的方法,强调以业务领域为核心进行设计与开发。它通过将业务逻辑与代码组织紧密结合,帮助开发团队更好地理解和实现业务需求。

2. DDD 核心概念

image-20241105070202575

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 和可变的属性,如 nameposition 等。
    • 值对象(Value Object):不具有唯一标识,仅通过属性定义对象的身份,通常是不可变的。比如,在一个地图应用中,Coordinate(坐标)可以是一个值对象,包含 latitude(纬度)和 longitude(经度)。
    • 聚合(Aggregate):是一组相关对象的集合,由一个聚合根(Aggregate Root)控制。聚合根负责与外部系统交互,并维护聚合内的数据一致性。例如,在一个电商系统中,Order 可以是一个聚合根,负责管理订单中的所有 OrderItem
    • 领域服务(Domain Service):当业务逻辑不属于单个实体或值对象时,使用领域服务来实现。比如,PaymentService 可以是一个领域服务,负责处理支付逻辑。
  • 职责
    • 实现所有核心业务逻辑。
    • 使用通用语言(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框架的项目结构

image-20241105070529623


http://www.mrgr.cn/news/65863.html

相关文章:

  • 如何生成 PEM 格式的 SSH 密钥 ?
  • 初识动态规划(由浅入深)
  • Android沙箱
  • 使用 `Celery` 配合 `RabbitMQ` 作为消息代理,实现异步任务的调度、重试、定时任务以及错误监控等功能
  • Freertos学习日志(1)-基础知识
  • 力扣题目解析--罗马数字转整型
  • 麻省理工学院的研究人员最近开发了一种新的机器人训练方法
  • 阿里云服务器 篇十:自动定时备份CSDN博客内容
  • 十四届蓝桥杯STEMA考试Python真题试卷第二套第五题
  • 【Java知识】java进阶-一个好用的java应用分析工具arthas
  • markdown/Latex希腊字母αβγ...λ...π等怎么编辑
  • sqlserver
  • 【C++ 曼哈顿距离 数学】1131. 绝对值表达式的最大值|2059
  • 模块功能的描述方法
  • 理解数据加载器(Data Loader)
  • OSI参考模型
  • Java 8的关键新特性:JDK加解密、Lambda表达式、日期时间API及Optional类
  • Vue全栈开发旅游网项目(6)-接口开发
  • Java 基本数据类型 和 输入输出语句
  • 【编程语言】Kotlin快速入门 - 泛型
  • 全面解析:云计算技术及其应用
  • 【Linux 27】HTTP 协议中的 cookie 和 session
  • C++算法练习-day34——257.二叉树的所有路径
  • MATLAB实现图像恢复设计报告
  • 掌握 In-Context Learning (ICL):构建高效 Prompt 的技巧与调优策略
  • Java | Leetcode Java题解之第539题最小时间差