DDD实战笔记(2) DDD领域驱动代码结构设计

1. DDD 分层架构与微服务代码模型

微服务代码模型就是依据DDD 分层架构模型设计出来的。那为什么是 DDD 分层架构模型呢?
DDD实战笔记(2) DDD领域驱动代码结构设计_第1张图片
用户接口层:面向前端提供服务适配,面向资源层提供资源适配。这一层聚集了接口适
配相关的功能。

应用层职责:实现服务组合和编排,适应业务流程快速变化的需求。这一层聚集了应用
服务和事件相关的功能。

领域层:实现领域的核心业务逻辑。这一层聚集了领域模型的聚合、聚合根、实体、值
对象、领域服务和事件等领域对象,以及它们组合所形成的业务能力。

基础层:贯穿所有层,为各层提供基础资源服务。这一层聚集了各种底层资源相关的服
务和能力。

2.微服务一级目录结构

微服务一级目录是按照 DDD 分层架构的分层职责来定义的。从下面这张图中,我们可以看 到,在代码模型里分别为用户接口层、应用层、领域层和基础层,建立了 interfaces、 application、domain 和 infrastructure 四个一级代码目录。
DDD实战笔记(2) DDD领域驱动代码结构设计_第2张图片
这些目录的职能和代码形态是这样的。

Interfaces(用户接口层):它主要存放用户接口层与前端交互、展现数据相关的代码。前 端应用通过这一层的接口,向应用服务获取展现所需的数据。这一层主要用来处理用户发送 的 Restful 请求,解析用户输入的配置文件,并将数据传递给 Application 层。数据的组 装、数据传输格式以及 Facade 接口等代码都会放在这一层目录里。

Application(应用层):它主要存放应用层服务组合和编排相关的代码。应用服务向下基 于微服务内的领域服务或外部微服务的应用服务完成服务的编排和组合,向上为用户接口层 提供各种应用数据展现支持服务。应用服务和事件等代码会放在这一层目录里。

Domain(领域层):它主要存放领域层核心业务逻辑相关的代码。领域层可以包含多个聚 合代码包,它们共同实现领域模型的核心业务逻辑。聚合以及聚合内的实体、方法、领域服 务和事件等代码会放在这一层目录里。

Infrastructure(基础层):它主要存放基础资源服务相关的代码,为其它各层提供的通用 技术能力、三方软件包、数据库服务、配置和基础资源服务的代码都会放在这一层目录里。

2.1 用户接口层

Interfaces 的代码目录结构有:assembler、dto 和 façade 三类。
DDD实战笔记(2) DDD领域驱动代码结构设计_第3张图片

Assembler:实现 DTO 与领域对象之间的相互转换和数据交换。一般来说 Assembler 与 DTO 总是一同出现。
Dto:它是数据传输的载体,内部不存在任何业务逻辑,我们可以通过 DTO 把内部的领域 对象与外界隔离。

Facade:提供较粗粒度的调用接口,将用户请求委派给一个或多个应用服务进行处理。

2.2 应用层

Application 的代码目录结构有:event 和 service。
DDD实战笔记(2) DDD领域驱动代码结构设计_第4张图片
Event(事件):这层目录主要存放事件相关的代码。它包括两个子目录:publish 和 subscribe。前者主要存放事件发布相关代码,后者主要存放事件订阅相关代码(事件处理 相关的核心业务逻辑在领域层实现)。
这里提示一下:虽然应用层和领域层都可以进行事件的发布和处理,但为了实现事件的统一管理,我建议你将微服务内所有事件的发布和订阅的处理都统一放到应用层,事件相关的核心业务逻辑实现放在领域层。通过应用层调用领域层服务,来实现完整的事件发布和订阅处
理流程。

Service(应用服务):这层的服务是应用服务。应用服务会对多个领域服务或外部应用服 务进行封装、编排和组合,对外提供粗粒度的服务。应用服务主要实现服务组合和编排,是 一段独立的业务逻辑。你可以将所有应用服务放在一个应用服务类里,也可以把一个应用服 务设计为一个应用服务类,以防应用服务类代码量过大。

2.3 领域层

Domain 是由一个或多个聚合包构成,共同实现领域模型的核心业务逻辑。聚合内的代码 模型是标准和统一的,包括:entity、event、repository 和 service 四个子目录。
DDD实战笔记(2) DDD领域驱动代码结构设计_第5张图片

Aggregate(聚合):它是聚合软件包的根目录,可以根据实际项目的聚合名称命名,比 如权限聚合。在聚合内定义聚合根、实体和值对象以及领域服务之间的关系和边界。聚合内 实现高内聚的业务逻辑,它的代码可以独立拆分为微服务。以聚合为单位的代码放在一个包里的主要目的是为了业务内聚,而更大的目的是为了以后微服务之间聚合的重组。聚合之间清晰的代码边界,可以让你轻松地实现以聚合为单位的微服务重组,在微服务架构演进中有着很重要的作用。

Entity(实体):它存放聚合根、实体、值对象以及工厂模式(Factory)相关代码。实体 类采用充血模型,同一实体相关的业务逻辑都在实体类代码中实现。跨实体的业务逻辑代码 在领域服务中实现。

Event(事件):它存放事件实体以及与事件活动相关的业务逻辑代码。

Service(领域服务):它存放领域服务代码。一个领域服务是多个实体组合出来的一段业 务逻辑。你可以将聚合内所有领域服务都放在一个领域服务类中,你也可以把每一个领域服 务设计为一个类。如果领域服务内的业务逻辑相对复杂,我建议你将一个领域服务设计为一 个领域服务类,避免由于所有领域服务代码都放在一个领域服务类中,而出现代码臃肿的问 题。领域服务封装多个实体或方法后向上层提供应用服务调用。
Repository(仓储):它存放所在聚合的查询或持久化领域对象的代码,通常包括仓储接 口和仓储实现方法。为了方便聚合的拆分和组合,我们设定了一个原则:一个聚合对应一个 仓储。

2.4 基础层

Infrastructure 的代码目录结构有:config 和 util 两个子目录。
DDD实战笔记(2) DDD领域驱动代码结构设计_第6张图片
Config:主要存放配置相关代码。

Util:主要存放平台、开发框架、消息、数据库、缓存、文件、总线、网关、第三方类库、通用算法等基础代码,你可以为不同的资源类别建立不同的子目录。

3.代码模型总目录结构

DDD实战笔记(2) DDD领域驱动代码结构设计_第7张图片

你可能感兴趣的:(DDD领域驱动)