DDD - 概述 - 模块 (二)

时间:2022-08-31 12:59:02

首先,你必须知道以下DDD构建块:

  1. Entities - 实体

  2. Value objects - 值对象

  3. Aggregate roots - 聚合跟

  4. Repositories - 仓储对象

  5. Factories - 工厂

  6. Services - 服务

 

1. 实体

一个实体是一个普通对象,有一个身份(ID)和可能是可变的。每个实体都由一个惟一标识ID而不是由一个属性;因此,如果他们两实体有相同的ID,两个实体可以被认为是相同的,即使他们有不同的属性。这意味着实体的状态随时可以改变,但只要两个实体具有相同的ID,都是相等的.

2. 值对象

值对象是不可变的。他们没有身份(ID)像我们发现实体。如果他们有相同的类型和属性(适用于所有的属性),那么这两个值对象可以被认为是相等的。有时候我们在我们的洋葱架构中需要进行消息传递的时候我们可以通过使用值对象去传递,从而能避免直接暴露领域对象.值对象的一些好处:

  1. 值对象的使用可以吞下大量的计算复杂度。

  2. 分解掉实体的部分逻辑,从而让实体的逻辑简化。

  3. 提高可扩展性,比如解决可测试性和并发性的问题.

3.聚合根

聚合根是一个实体与其他实体结合在一起。此外,聚合根实际上是一个总体的一部分(收集/集群相关的对象当作一个单独的单元为目的的数据改变)。因此,每个聚合实际上由一个聚合根和一个边界构成。比如,在销售订单 中,订单Order和订单项OrderLineItem可以被认为是一个聚合,这里的Order(订单)是聚合根对象,这个订单项(orderlineItem)就是订单的子对象.一个聚合根的关键特性之一就是外部对象不允许持有一个聚合根子实体。因此,如果您需要访问一个聚合根子实体(即总),那么你必须经过聚合根(即不能直接访问某一个聚合的子对象)。另一个是域内的所有操作应在可能的情况下,经过一个聚合根。工厂、仓库和服务有一些例外.

4. 仓储

仓库主要是用来处理存储。在DDD中它是一个最重要的概念.因为他们有大量的存储问题中抽象出来(即某种形式/存储机制)。可能是一个基于文件的存储库实现存储,或数据库(SQL - / NoSQL-based),或任何其他有关存储机制,如缓存。任意组合的也是可能的。仓储与数据存储不是一个东西不要混淆。仓储是为数据存储(数据库)服务的。仓储的实现可能需要使用到多个数据源对象。因此,一个聚合根可能来自一个REST API,以及数据库或文件。你可能包装那些所谓的数据存储,但存储库是一种进一步的抽象层上所有的个人数据存储。通常,我实现域/域内的存储库为一个接口服务层内洋葱架构,然后存储库的实现逻辑接口中定义的基础设施层。

5. 工厂

就是我们通常理解的工厂的概念,在DDD中,确切地说在聚合对象中,工厂通常用来返回 一个聚合跟 或一个实体或 一个值对象.很多时候,当你需要一个聚合根的工厂方法,在repository(仓储中)使用。因此,(repository)存储库可能有一个查找器创建方法。通常的 工厂是在domain/domain services layer(领域或领域服务层)定义的接口对象,实现逻辑是在infrastructure layer(基础设施曾)中的. 也就是说 infrastructure 中定义的是 domain/domain service层的工厂接口的实现.

6. 服务

某一部分的操作并不好归结到某一个领域对象,并不适合创建聚合,那么这时候可以考虑创建成services(服务)对象.

其他

我经常发现许多开发人员使用术语VO(值对象)和DTO(数据传输对象)互换。他们认为都是相同的。这对我来说很烦人。这里我想澄清,指的是不同的东西。下图中所示,签证官和DTO的子集POJO /少。一个实体POJO /少也是一个子集。在上面的描述,POJO和少可以互换使用。都是指的是类似的事情。都只是域对象,主要代表域/业务应用程序中的业务对象。POJO(传统的普通Java对象)这个词是由马丁在Java社区,非常受欢迎,而少(普通CLR对象/普通类对象)被广泛用于dotNet。如前所述,DTO,签证官和实体POJO /少的只是一个子集.DTO只是一个简单的数据载体(只有持有数据没有任何逻辑)。因此,它的一般贫血(只包含属性和getter / setter)。DTO绝对是不可变的。通常,我们使用DTO转让对象层和层之间的一个应用程序或应用程序到应用程序或JVM JVM(主要是有用的网络之间减少多个网络调用)。