怎么解释ABP 的DDD 设计模式

发布时间 2023-08-14 10:51:56作者: skywss27

ABP的DDD设计模式,就是将传统的开发模式,根据领域驱动设计(Domain Driven Design,简称DDD)的理念,调整为一个理念更清晰,结构更合理的新的开发模式。ABP框架对DDD的概念进行了实际的运用,有助于提高开发效率,降低系统复杂性,方便系统的维护和扩展。

领域驱动设计主要围绕以下几个重要的概念进行:

实体(Entity): 有自己的身份标识,与具体的业务概念直接对应。如:用户、订单等。
  1. 在领域驱动设计(DDD)中,实体(Entity)是一种引用对象,它具有持久的唯一标识(ID)和在创建后可以发生状态变化的特性。实体的主要特点是它有一个在整个生命周期里都不会改变的唯一标识。实体的相等性会基于唯一标识,而不仅仅基于属性值。这就意味着,即使两个实体的所有属性都一样,但如果他们的ID不同,那么他们就被视为不同的实体。
    以用户为例,"用户"是一个常见的实体,它可能有诸如"用户名","电子邮件","密码"等属性,甚至某些属性(如电子邮件)可能必须是唯一的。但是,无论这些属性如何变化,只要用户的ID(如用户ID)不变,那么就认为是同一个用户。我们可以更改用户的用户名,电子邮件等但是其ID一般不变。这种方式有助于我们处理复杂的业务模型,并保持业务领域的完整性和一致性。
值对象(Value Object): 无需唯一身份标识,通常是用来描述实体的特性。
  1. 在领域驱动设计(DDD)中,值对象是一个不可变的对象,它包含了一些属性但没有唯一的身份标识。值对象的相等性不是基于对象的ID,而是基于对象的属性值。由于没有实体标识和唯一性,它们可以自由地创建和销毁。比如,我们用"日期"来作为一个例子。日期如“2022年3月10日”是一个值对象,它没有实体ID,只是代表一个特定日期的对象。对于任何表示同一日期(即属性值相同)的日期对象,我们都可以认为它们是等价的。即使我们创建一百个代表“2022年3月10日”的不同对象,这些对象都被认为是“等价的”或“相同的”,与我们只创建一个代表“2022年3月10日”的对象没有什么区别。又比如,购物车中的"商品项"也可以被看作是值对象。一个商品项可能包括商品ID、商品数量和商品价格,而我们并不关心这些商品项是在什么时间被添加到购物车的,也不关心它们在购物车里的排序,这些商品项就是值对象。
聚合(Aggregate): 由实体和值对象构成的一个业务单元,对外表现为一个整体。
  1. 在领域驱动设计(DDD)中,聚合(Aggregate)是将一组有关联的对象集合到一起,作为处理数据和行为的单元。聚合定义了一组对象如何相互协作,目的是封装业务逻辑、保持数据的一致性。聚合有一个根(Aggregate Root),这个根是外部对象和聚合内部对象交互的唯一途径。根据实际业务规定,应定义清晰的边界以区分哪些对象应纳入聚合。通常,仓储只直接管理这个根对象。比如:在电商系统中,“订单”可能就是一个典型的聚合,包含多个实体和值对象,如“订单明细”,“支付信息”,“收货地址”等。"订单"就是这个聚合的根。在这个系统中,所有对"订单明细","支付信息","收货地址"的操作,都必须通过"订单"这个聚合根来进行。这样设计的目的,就是要确保业务规则的一致性和完整性。比如,不允许创建没有订单明细的订单,每笔订单必须有一个有效的收货地址等。
领域事件(Domain Event): 领域对象的状态变化产生的事件,表示一种业务行为。
  • 领域事件是指在领域模型中发生的重要事情,它们代表着业务流程中的关键步骤或状态变化。领域事件可以是系统内部的事件,也可以是与外部系统进行交互时发生的事件。在领域驱动设计中,领域事件是一种重要的概念,它可以用于实现事件驱动架构(EDA)。通过使用领域事件,我们可以将业务逻辑和业务流程分离出来,使得系统更加灵活和易于扩展。在实现领域事件时,我们通常会定义一个事件模型,用于描述事件的属性和行为。当领域模型中发生了某个事件时,我们可以在事件模型中记录下相应的信息,并将其发布到一个消息队列或事件总线中,以便其他系统或模块可以接收到该事件并做出相应的处理。这样,我们就可以实现系统内部的解耦和外部系统的集成。
仓储(Repository): 提供查找、存储对象的方法,通常与持久化相关。
  • 仓储是一种设计模式,用于管理应用程序中的领域对象的持久化和检索。在领域驱动设计中,仓储是一种重要的概念,它用于将领域模型与数据存储技术分离开来,从而实现系统的可维护性、可测试性和可扩展性。

  • 在实现仓储时,我们通常会定义一个接口,用于描述仓储的基本操作,如添加、修改、删除和查询等。然后,我们可以通过实现这个接口来实现具体的数据存储和检索功能。在领域模型中,我们可以通过依赖注入等方式来使用仓储,从而实现领域对象的持久化和检索。

  • 使用仓储模式可以使领域模型与数据存储技术解耦,从而使系统更加灵活和易于维护。此外,通过使用仓储模式,我们还可以实现对数据访问的统一管理,从而提高系统的性能和可靠性。

领域服务(Domain Service): 实现领域模型的业务逻辑。
  • 领域服务是一种服务,它封装了领域模型中的业务逻辑,提供了一些特定的操作,用于实现领域对象之间的交互和协作。领域服务通常是无状态的,它们不持有任何状态,只是提供了一些操作方法,用于实现业务逻辑。
应用服务(Application Service): 对外提供接口,调用领域层的相关操作。
  • 应用服务是一种服务,它封装了应用程序中的业务逻辑,主要负责协调领域对象和其他应用程序层之间的交互。应用服务通常是有状态的,它们持有一些状态信息,以便在处理业务逻辑时进行跟踪和管理。
在实现应用程序时,我们通常会使用领域服务和应用服务来实现业务逻辑。领域服务用于封装领域模型中的业务逻辑,而应用服务则用于协调领域对象和其他应用程序层之间的交互。通过使用这两种服务,我们可以将业务逻辑清晰地分离出来,并实现系统的可维护性、可测试性和可扩展性。