初识DDD

DDD领域驱动设计

1 DDD是什么?

领域驱动设计(Domain-Driven Design, DDD)是一种软件设计方法论,旨在处理复杂的业务需求和系统设计。由Eric Evans在他的同名书中提出,DDD关注将业务需求和软件架构紧密结合,通过领域模型和相应的设计模式,创建灵活且可维护的系统。

1.1 领域驱动设计的优势
  • 解决复杂性:通过将复杂的业务需求分解成更小的子域和限界上下文,DDD帮助开发人员更好地理解和管理复杂性。
  • 业务与技术的统一:通过领域模型和共同的语言,业务人员和技术团队可以更高效地沟通和协作。
  • 灵活性和可维护性:DDD设计的系统具有更高的灵活性和可维护性,能够更好地适应业务变化。
1.2 领域驱动设计的应用场景

DDD非常适用于具有高度复杂性和业务逻辑的系统,如电商平台、金融系统、物流管理等。但并非所有项目都适合使用DDD,对于一些简单的系统,可能不需要这么复杂的设计方法。

领域驱动设计通过清晰的领域划分和模型设计,应对复杂的软件系统,确保系统的稳定性、扩展性和灵活性。

2 领域驱动设计(DDD)概念

领域驱动设计(Domain-Driven Design, DDD)是一种为了解决复杂软件设计而提出的优秀方案,但并非唯一的方法。

2.1 核心概念
  • 领域: 领域是指所有业务规则、定义、范围、知识等的抽象概念。比如,用户支付业务属于交易域,平台提供售后服务属于服务域(或客服域),其他如金融域、人效域、物流域等。
  • 分而治之: 通过把复杂的领域(问题)分解成更小的子域,每个子域都有明确的边界和核心实体。通过一系列的拆分、归类、衍生,找到最优解。
2.2 应对复杂性的策略
  1. 保持内核稳定性和扩展性: 在多变的业务环境中,通过稳定的内核设计,确保系统的扩展性和灵活性。
  2. 领域模型的共识性: 领域模型贯穿了从设计到交付的软件生命周期,开发、产品、架构师围绕统一的模型进行设计和讨论,确保一致性。
2.3 领域模型的特点
  • 图形表达方式: 除了实体模型图的表达比较特殊,其他如时序图、状态机、流程图等表达方式与其他方法并无不同。
  • 业务的抽象: 领域模型是对业务的抽象,基于现实但不等于现实。

3 DDD和MVC的比较

在DDD理念提出来之前,最经典的开发模式就是MVC了。

3.1 MVC组成部分

**1.Model(模型)**
  • 职责:处理业务逻辑和数据。模型负责与数据库交互,进行数据的CRUD(创建、读取、更新、删除)

  • 实现:在图中,Model使用JavaBean来封装数据和业务逻辑。JavaBean类通常包含属性、getter和setter方法,以及一些业务逻辑方法。

    2.View(视图)

  • 职责:负责展示数据给用户。视图从模型获取数据,并将其以用户友好的方式展示出来。

  • 实现:在图中,View使用JSP(JavaServer Pages)来显示前端页面。JSP文件包含HTML代码,并且可以嵌入Java代码来动态显示数据。

    3.Controller(控制器)

  • 职责:作为模型和视图之间的中介,处理用户输入,调用模型来处理数据,并将结果交给视图进行展示。

  • 实现:在图中,Controller使用Servlet来实现。Servlet接收客户端的请求,调用相应的JavaBean处理业务逻辑,然后将数据转发给JSP页面进行展示。

3.2 MVC工作流程

  1. 用户请求
  • 用户通过浏览器发送请求到服务器。
  1. Controller接收请求
  • Servlet作为Controller,接收客户端的请求。

  • Controller获取用户输入,调用相应的模型进行处理。

  1. 调用模型(Model)
  • Controller调用JavaBean(模型)进行业务逻辑处理,例如查询数据库。

  • JavaBean执行数据操作,并返回处理结果。

  1. 将数据传递给视图(View)
  • Controller将处理结果(数据)传递给JSP页面(视图)。

  • JSP页面接受数据并进行展示。

  1. 显示数据
  • 浏览器接收服务器返回的HTMl页面,并将结果显示给用户。

3.3 MVC架构存在的问题

  1. 控制器过于臃肿
  • 包含大量业务逻辑,导致难以维护。
  1. 模型职责不明确
  • 业务逻辑、数据访问混杂,模型变得复杂。
  1. 视图层逻辑复杂化
  • 需要大量数据处理和格式化操作,代码难以维护。
  1. 模块间耦合度高
  • 各层之间调用关系复杂,难以单独测试和调试。
  1. 难以应对复杂业务场景
  • 频繁修改代码,系统难以适应新需求。
  1. 数据一致性问题
  • 难以保证数据一致性,可能导致数据错误。
  1. 缺乏领域层的抽象
  • 业务逻辑分散,维护复杂业务规则困难。

MVC架构适用于简单业务场景,但在面对复杂、多变的业务需求时,容易出现控制器和模型臃肿、模块耦合度高、数据一致性难保证等问题,导致系统难以维护和扩展。

4 DDD可以带来的价值

4.1 团队价值

  • 统一语言

  • 清晰的边界定义

  • 领域能力沉淀和复用

  • 面向业务建模

  • 设计和代码的等价

4.2 个人价值

  • 提升全局视野

  • 提升业务sense

  • 构建体系化思维

5 领域驱动设计的核心概念

5.1 DDD完整设计流程

  1. 提炼业务流程

在这个阶段,目标是对业务进行深入理解和分析,以便为后续的设计奠定基础。这包括:

  • 角色:确定在业务流程中涉及的不同角色。
  • 业务事件:识别关键的业务事件,这些事件通常是引发系统行为的触发器。
  • 参与者:确定业务流程中所有参与者,他们可能是用户、系统或其他外部实体。
  • 流程:梳理业务流程,明确各个步骤和环节。
  • 描述:对上述元素进行详细描述,确保每个元素都得到充分理解。
  1. 战略设计

这一阶段主要是从宏观角度对业务进行架构设计,定义系统的高层次结构和边界。具体包括:

  • 领域:划分业务领域,定义系统的核心业务领域。
  • 子域:将领域进一步细分为子域,每个子域对应一个相对独立的业务模块。
  • 通用域:识别通用领域,这些领域包含在多个子域中共享的业务逻辑。
  • 支撑域:确定支撑域,这些领域为核心业务领域提供辅助功能。
  • 限界上下文:定义每个子域的边界和上下文,明确子域之间的接口和交互方式。
  1. 战术设计

在战术设计阶段,重点是具体的技术实现和细节设计,主要包括:

  • 实体:定义业务中的实体,它们通常是具有唯一标识和生命周期的对象。
  • 值对象:定义值对象,这些对象没有唯一标识,通常用于描述某些属性或值。
  • 聚合:将相关的实体和值对象组合成聚合,通过聚合根来管理。
  • 聚合根:确定每个聚合的根实体,聚合根负责聚合内部的一致性。
  • 资源库:定义资源库,用于管理实体的持久化和检索。
  • 工厂:使用工厂模式来创建复杂的对象,简化对象的创建过程。
  • 领域服务:定义领域服务,这些服务包含跨多个实体和值对象的业务逻辑。
  • 领域事件:定义领域事件,捕捉和传递领域内的重要事件。
  1. 编码

最后一步是根据战术设计进行编码实现:

  • 代码分层:根据战术设计将代码进行分层,实现清晰的代码结构。
  • 依赖注入:使用依赖注入和其他设计模式,确保系统的模块化和可测试性。
  • 单元测试:编写单元测试,确保每个模块和组件的功能正确。

5.2 核心概念

  1. 领域(Domain)
  • 领域是指特定业务范围内的知识、逻辑和规则的集合。它包括所有与业务相关的定义和概念。
  1. 子域(Subdomain)
  • 将大的领域划分成更小的子域,每个子域代表一个特定的业务问题或功能。通过分解,复杂的问题变得更易于管理。
  1. 限界上下文(Bounded Context)
  • 定义领域模型的边界。在每个限界上下文内,特定的术语和规则有明确的含义,不同的限界上下文可能有不同的模型和规则。
  1. 领域模型(Domain Model)
  • 领域模型是对业务领域的抽象和表示,包括实体(Entities)、值对象(Value Objects)、聚合(Aggregates)、领域事件(Domain Events)等元素。领域模型是开发、产品、架构师等各方达成共识的核心。
  1. 聚合(Aggregate)
  • 聚合是具有一致性的聚合根及其相关对象的集合。聚合根负责聚合的状态一致性,并确保业务规则的执行。
  1. 实体(Entity)
  • 实体具有唯一标识和可变状态,是业务操作的核心对象。
  1. 值对象(Value Object)
  • 值对象没有唯一标识,通常是不可变的,代表特定的业务值。
  1. 领域服务(Domain Service)
  • 领域服务封装了跨实体或值对象的业务逻辑,提供特定领域的操作和功能。

6 领域建模

领域建模是DDD最关键的部分,它的目的归纳起来就是:提炼业务知识,形成统一语言,沉淀领域模型。

领域建模是领域驱动设计(DDD)的核心步骤,它通过将复杂的业务需求和规则转化为可管理的领域模型,使开发团队能够更好地理解和实现业务逻辑。以下是领域建模的主要步骤:

6.1 了解业务领域

  • 业务调研:与业务专家、用户和相关方进行深入交流,理解业务需求、目标和痛点。
  • 业务流程分析:梳理和分析业务流程,明确业务操作、角色和参与者。

6.2 提炼领域概念

  • 识别实体(Entity):找出具有唯一标识和生命周期的对象。例如,订单、客户等。
  • 识别值对象(Value Object):找出没有唯一标识、用来描述某些属性的对象。例如,地址、货币等。
  • 识别聚合(Aggregate):将相关的实体和值对象组合成聚合,通过聚合根来管理。例如,订单聚合包括订单实体、订单项值对象等。
  • 识别领域服务(Domain Service):找出跨多个实体和值对象的业务逻辑。例如,支付服务、库存检查服务等。

6.3 定义限界上下文(Bounded Context)

  • 划分子域:根据业务领域和业务流程,将系统划分为多个子域,每个子域对应一个相对独立的业务模块。
  • 明确上下文边界:定义每个子域的边界,明确子域之间的接口和交互方式,确保子域内部的一致性。

6.4 设计领域模型

  • 创建实体和值对象:设计实体和值对象的属性和行为,确保它们能够充分表达业务逻辑。
  • 定义聚合根:确定每个聚合的根实体,聚合根负责管理聚合内部的一致性。
  • 设计资源库(Repository):定义资源库接口,用于管理实体的持久化和检索。
  • 实现领域服务:设计领域服务的接口和实现,将复杂的业务逻辑封装在领域服务中。
  • 设计领域事件(Domain Event):定义领域事件,捕捉和传递领域内的重要事件。

6.5 验证和迭代

  • 与业务专家验证:与业务专家持续沟通,验证领域模型是否正确反映了业务需求。
  • 迭代优化:根据反馈不断迭代和优化领域模型,确保其准确性和实用性。

6.6 实现和测试

  • 代码实现:根据领域模型进行代码实现,确保每个模型元素都得到正确实现。
  • 单元测试:编写单元测试,验证领域模型的各个部分是否正确工作。
  • 集成测试:进行集成测试,确保各个子域和组件之间的协作正常。

6.7 总结

领域建模是一个持续迭代的过程,贯穿于项目的整个生命周期。通过领域建模,可以将复杂的业务需求转化为清晰的领域模型,提高系统的可理解性、可维护性和可扩展性。以下是领域建模的主要步骤总结:

  1. 了解业务领域:深入理解业务需求和流程。
  2. 提炼领域概念:识别实体、值对象、聚合、领域服务等。
  3. 定义限界上下文:划分子域,明确上下文边界。
  4. 设计领域模型:创建和设计实体、值对象、聚合根、资源库、领域服务和领域事件。
  5. 验证和迭代:与业务专家验证模型,持续优化。
  6. 实现和测试:代码实现和单元测试,确保模型的正确性。

开源项目推荐

GitHub - lml200701158/ddd-framework: DDD框架

GitHub - Air433/dddbook: spring boot 领域驱动设计Demo

GitHub - EalenXie/spring-microservice-ddd: 微服务+DDD代码结构例子

GitHub - louyanfeng25/ddd-demo: MVC【以mybatis-plus为orm框架】迁移至DDD的demo

GitHub - dddplus/dddplus-demo: ♨️ Demonstrate how to use DDDplus to build a complex OMS.演示如何使用DDDplus实现一套订单履约中台OMS

GitHub - xlorne/springboot-ddd-demo: 如何做好一个项目?springboot与领域模型该如何结合?

  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值