领域驱动设计-基础篇

Mr.LR2024年5月5日
大约 13 分钟

基础篇

为什么要选择DDD

DDD有助于更好地理解业务、降低开发风险、提高质量、加速开发,以及更好地适应复杂领域。

领域、子域、核心域、通用域和支持域

领域和子域

在领域驱动设计中,领域和子域是两个重要的概念,用于帮助组织和划分软件系统的不同部分,以便更好的理解和设计系统。

领域

  • 领域是指问题领域或业务领域,它代表了软件系统所要解决的现实世界的一部分。
  • 领域包括了与业务相关的所有概念、规则、流程和数据。这些概念可以是实体、值对象、聚合根、仓储等。
  • 领域是系统的核心,DDD强调开发团队应该深入理解领域,以便更好地设计和实现与之相关的软件模块。

子域

  • 子域是指在整个领域中的一个更小的、特定的部分,通常代表业务领域的一个子集或某个特定的功能领域。
  • 大型软件系统通常包含多个子域,每个子域都有自己的模型、规则和语言。
  • 子域之间可能存在关联,但它们是相对独立的,可以由不同的团队负责开发和维护。
  • 通过将领域划分为子域,可以降低系统复杂性,提高系统的可维护性,并允许不同团队专注于其领域的问题。

例如:在电子商务领域,又可以划分如下几个子域

商品管理子域

  • 这个子域关注产品的创建、编辑、删除和管理。
  • 它包含了与产品相关的概念,如产品目录、产品属性、价格策略等。
  • 商品管理子域可以有自己的领域模型和规则,专门处理产品管理方面的逻辑。

订单处理子域

  • 这个子域关注订单的创建、处理、支付和配送。
  • 它包含了与订单相关的概念,如购物车、订单状态、支付方式等。
  • 订单处理子域可以有自己的领域模型和规则,专门处理订单流程和付款逻辑。

用户账户子域

  • 这个子域关注用户的注册、登录、个人信息管理等。
  • 它包含了用户、身份验证、个人资料等概念。
  • 用户账户子域可以有自己的领域模型和规则,专门处理用户管理和身份验证逻辑。

通过将领域划分为不同的子域,可以更好地管理系统的复杂性,并使不同的团队或模块专注于各自领域的开发和维护。每个子域都可以有自己的聚合根、实体、值对象以及与其他子域的界限上下文,以确保领域模型的一致性和可维护性。这有助于在大型软件系统中更好地理解和处理业务逻辑。

核心域、通用域和支撑域

在领域不断划分的过程中,领域会细分为不同的子域,子域可以根据自身重要性和功能属性划分为三类子域 ,它们分别是:核心域、通用域和支撑域。它们有助于更好地组织和管理领域内的代码和业务逻辑。

核心域

核心域是在整个应用程序中至关重要的领域,它包含了与业务的竞争优势和关键不可或缺的部分相关的领域逻辑。

通用域:

通用域是与业务有关但不是核心竞争优势的部分,它包括了业务中的通用概念和逻辑。

通用域通常包括一些通用的、通用性的领域逻辑,可以在多个项目和领域之间重复使用

支撑域:

支撑域是与业务无关的部分,它包括了不直接与核心或通用领域相关的技术、工具、框架和基础设施。

支撑域中的代码和逻辑通常不会直接映射到业务需求,但它们对于系统的整体运行非常重要

例如:在电子商务领域,可以如下划分

核心域

核心域代表了电子商务系统中的关键业务领域,这是系统最核心、最具竞争优势的部分

  • 订单管理核心域:负责订单的创建、处理、支付、发货和退款。
  • 产品管理核心域:负责产品的管理、上架、价格管理等。
  • 用户账户核心域:负责用户的注册、登录、个人信息管理、购物车等。

通用域

通用域包含了电子商务系统中与核心业务相关但不是竞争优势的通用概念和逻辑

  • 支付通用域:提供通用支付处理逻辑,可以在不同支付方式和核心领域之间共享。
  • 库存通用域:提供库存管理逻辑,用于跟踪产品库存并更新产品可用性。

支撑域

支撑域包含了电子商务系统中与业务无关的技术、工具、框架和基础设施。

  • 身份认证支撑域:提供用户身份认证和授权服务,用于保护核心和通用领域。
  • 日志支撑域:提供日志记录和监控服务,用于跟踪系统的运行状况。
  • 缓存支撑域:提供缓存服务,以改善系统性能。

限界上下文

限界上下文(Bounded Context)是一个核心概念,它有助于将大型电子商务系统分割成更小、更可管理的部分,以便更好地理解、开发和维护系统。

电子商务系统中的限界上下文示例:

订单管理上下文(Order Management Context)

  • 在这个上下文中,重点关注订单的创建、处理、支付、发货和退货等操作。
  • 核心领域对象包括订单、购物车、支付、发货等。
  • 在此上下文中,订单的状态、生命周期和支付验证是关键概念。
  • 此上下文可能包括有关促销、折扣和优惠券的业务规则。

产品管理上下文(Product Management Context)

  • 该上下文负责管理产品的信息,包括产品的分类、描述、价格等。
  • 核心领域对象包括产品、商品目录、价格策略等。
  • 产品状态、库存数量以及与商品分类相关的规则是关键概念。
  • 此上下文可能包括商品搜索和过滤功能。

用户账户上下文(User Account Context)

  • 该上下文关注用户的账户、个人信息、购物车和订单历史等。
  • 核心领域对象包括用户、身份验证、个人资料、购物车等。
  • 用户的身份验证、权限管理、购物车状态和用户个人信息管理是关键概念。
  • 此上下文可能包括与安全性、隐私保护和访问控制相关的业务规则。

支付上下文(Payment Context)

  • 该上下文处理支付和资金转移相关的业务。
  • 核心领域对象包括支付、交易、支付方式等。
  • 支付流程、交易状态和支付验证是关键概念。
  • 此上下文可能包括与金融机构接口、支付处理、欺诈检测和结算有关的逻辑。

每个限界上下文都有自己的领域模型、规则、术语和语言。这些上下文之间的边界清晰定义了它们的职责和关注点,使不同团队能够独立开发和维护各自的上下文。同时,通过明确定义上下文之间的接口和数据共享方式,可以确保系统的一致性。

限界上下文和微服务的关系

  • 限界上下文通常与微服务的边界相对应。每个微服务可以看作是一个限界上下文的实现,它包含了特定领域的业务逻辑和数据。
  • 每个微服务在实施时应该具有清晰的限界上下文,这有助于确定微服务的边界、领域模型和API。
  • 微服务架构通过将系统拆分成多个小型服务,每个服务都有自己的限界上下文,从而提供了更高的可伸缩性、独立部署和灵活性。

总结起来,限界上下文是DDD中的一个概念,用于帮助理解和建模系统的不同领域。微服务是一种架构风格,它通过将系统拆分成多个小型服务来提高可伸缩性和灵活性。在微服务架构中,每个微服务都应该有明确定义的限界上下文,这有助于确保微服务的独立性和可维护性。因此,限界上下文和微服务之间存在密切的关系,它们一起用于构建复杂系统的组织和架构。

实体和值对象

在领域驱动设计(Domain-Driven Design,DDD)中,实体(Entities)和值对象(Value Objects)是两个重要的概念,用于表示领域模型中的不同种类的对象。

让我们使用电子商务系统举例,详细解释这两个概念。

实体(Entities)

实体代表具有唯一标识的领域对象,其生命周期可以跨越多个状态和时间点。实体的标识通常是持久性的,意味着无论其属性如何变化,标识仍然保持不变。

在电子商务系统中的实体示例:

产品(Product):产品通常是实体,因为它们具有唯一的标识,如产品ID或SKU。产品的属性可能包括名称、描述、价格和库存数量。产品可以在系统中存在很长时间,其属性可以随时间变化,但产品的唯一标识仍然不变。

订单(Order):订单也是实体,因为每个订单都有一个唯一的订单号或标识符。订单的属性包括订单明细、状态、配送地址等。订单的生命周期可能包括创建、支付、发货和完成等多个状态。

用户账户(User Account):用户账户是实体,因为每个用户都有一个唯一的用户ID或用户名。用户账户的属性包括用户名、密码哈希、电子邮件地址等。用户账户的生命周期可以跨越很长一段时间,包括注册、登录、购物和管理个人信息。

值对象(Value Objects):

值对象代表没有唯一标识的领域对象,它们的身份由其属性定义。值对象通常是不可变的,它们的值在创建后不会发生变化。如果两个值对象的所有属性值都相同,它们就被认为是相等的。

在电子商务系统中的值对象示例:

配送地址(Shipping Address):配送地址通常被视为值对象,因为它们没有唯一标识,而是由一组属性(如街道、城市、邮政编码)定义。如果两个订单具有相同的配送地址属性值,它们可以视为相同的地址。

价格(Price):产品价格通常被视为值对象,因为它们由金额和货币单位属性组成。如果两个产品具有相同的价格,它们可以视为具有相同的价值。

购物车明细(Shopping Cart Item):购物车中的商品明细也可以被视为值对象,因为它们通常由产品、数量和价格组成。如果两个购物车明细具有相同的属性值,它们可以视为相等。

总之,实体代表有唯一标识和生命周期的领域对象,而值对象代表没有唯一标识、身份由属性定义的领域对象。在电子商务系统中,产品、订单和用户账户等通常是实体,而配送地址、价格和购物车明细等通常是值对象。理解这两个概念有助于更好地建模和处理领域中的不同种类的对象。

聚合和聚合根

在领域驱动设计(Domain-Driven Design,DDD)中,聚合(Aggregates)和聚合根(Aggregate Root)是用于组织和管理领域对象的关键概念,有助于维护领域模型的一致性和完整性。让我们使用电子商务系统来详细说明这两个概念。

聚合(Aggregates):

聚合是一组相关的领域对象的集合,它们一起被视为一个单元。聚合包括一个聚合根和其它聚合成员。聚合根是聚合的入口点,它负责维护聚合内部对象的完整性,并协调它们之间的操作。聚合根也是唯一可以从外部访问聚合内部对象的对象。

在电子商务系统中的聚合示例:

订单聚合(Order Aggregate):

  • 聚合根(Aggregate Root):订单(Order)是订单聚合的聚合根。订单负责协调订单项(Order Item)、付款(Payment)、配送地址(Shipping Address)等聚合成员的操作。
  • 聚合成员:订单项、付款信息和配送地址等都是订单聚合的成员。它们与订单有关,但不能被单独访问或修改,必须通过订单进行管理。

聚合根(Aggregate Root):

聚合根是聚合的一部分,它是聚合的入口点,负责维护聚合内部对象的完整性和一致性。只有聚合根才能从外部访问聚合内部对象,所有的操作都通过聚合根进行。

在电子商务系统中的聚合根示例:

订单聚合中的聚合根:

  • 订单(Order)是订单聚合的聚合根。
  • 所有与订单相关的操作,如创建订单、添加订单项、更新订单状态、提交订单等,都通过订单对象进行。

聚合的一致性边界:

聚合定义了一致性边界,这意味着在处理聚合内部对象时,它们的状态必须保持一致。这有助于确保领域模型的完整性和数据的正确性。

例如,在电子商务系统中,如果要更新订单的状态和库存数量,必须通过订单聚合的聚合根(订单)进行。这样可以防止不一致的状态变化,确保订单和库存数据的一致性。

总之,聚合和聚合根是DDD中用于组织和维护领域模型的重要概念。在电子商务系统中,订单聚合是一个常见的示例,其中订单是聚合根,负责管理订单项、付款信息等聚合成员的操作,同时维护数据一致性和完整性。这有助于更好地组织复杂的领域模型并确保数据的一致性。