DDD全称为(Dimain-Driven Design,简称DDD)领域驱动设计。
一、分层说明
用户接口层: 面向前端提供服务适配,面向资源层提供资源适配。这一层聚集了接口适配相关的功能。
应用层职责: 实现服务组合和编排,适应业务流程快速变化的需求。这一层聚集了应用服务和事件相关的功能。
领域层: 实现领域的核心业务逻辑。这一层聚集了领域模型的聚合、聚合根、实体、值对象、领域服务和事件等领域对象,以及它们组合所形成的业务能力。
基础层: 贯穿所有层,为各层提供基础资源服务。这一层聚集了各种底层资源相关的服务和能力。
在服务中也可以通过 DDD 分层架构来定义包结构目录。
在代码模型里分别为用户接口层、应用层、领域层和基础层,建立了 interfaces、application、domain 和 infrastructure 四个一级代码目录。
Interfaces(用户接口层): 它主要存放用户接口层与前端交互、展现数据相关的代码。前端应用通过这一层的接口,向应用服务获取展现所需的数据。这一层主要用来处理用户发送的 Restful 请求,解析用户输入的配置文件,并将数据传递给 Application 层。数据的组装、数据传输格式以及 Facade 接口等代码都会放在这一层目录里。
Application(应用层): 它主要存放应用层服务组合和编排相关的代码。应用服务向下基于微服务内的领域服务或外部微服务的应用服务完成服务的编排和组合,向上为用户接口层提供各种应用数据展现支持服务。应用服务和事件等代码会放在这一层目录里。
Domain(领域层): 它主要存放领域层核心业务逻辑相关的代码。领域层可以包含多个聚合代码包,它们共同实现领域模型的核心业务逻辑。聚合以及聚合内的实体、方法、领域服务和事件等代码会放在这一层目录里。
Infrastructure(基础层): 它主要存放基础资源服务相关的代码,为其它各层提供的通用技术能力、三方软件包、数据库服务、配置和基础资源服务的代码都会放在这一层目录里。
二、DDD分层架构设计(依赖关系)
三、包目录结构
┌─main
├─java
│ └─com
│ └─lyy
│ └─PROJECT 项目名
│ ├─application 应用层
│ │ ├─event 领域事件,具体业务下发至各个领域中进行处理
│ │ │ ├─publish 生产者
│ │ │ └─subscribe 消费者
│ │ └─service 应用服务,编排组合领域服务
│ ├─domain 领域层
│ │ └─order 业务包名
│ │ ├─entity 数据库表对象
│ │ ├─event 领域事件实体/具体事件业务处理
│ │ ├─repository 仓储层
│ │ ├─dao/mapper 数据库访问
│ │ └─service 领域服务
│ ├─infrastructure 基础层
│ │ ├─config 应用配置
│ │ │ └─apollo
│ │ ├─scheduled 定时任务
│ │ ├─remote 远程调用
│ │ └─util 工具类
│ └─interfaces 用户接口层
│ ├─assembler 实现DTO和领域对象转换
│ ├─dto 数据传输载体
│ └─facade 对外接口: rest, grpc, ws
└─resources
└─mapper
四、合理的架构分层
不要把与领域无关的业务逻辑放在领域层,避免领域业务逻辑被污染,保证领域层的纯洁,只有这样才能降低领域逻辑受外部变化的影响。在领域和架构模型建立后,代码模型的逻辑分层和微服务拆分要具体情况具体分析,根据自身研发和运维能力综合考虑。
对于单应用系统的分层,遵循上述分层架构模型即可,核心领域逻辑在领域层实现,服务的组合和编排在应用层实现,两者组合形成中台,通过 API 对前台应用提供服务。
从部署和微服务拆分来讲,领域层代码部署时可能是一个微服务,也可能会根据限界上下文被拆分为多个微服务部署。应用层代码如果逻辑复杂,含较多个性业务逻辑,可以根据需要独立为微服务部署;如果逻辑简单,且领域层是一个微服务,在划分好应用层和领域层代码逻辑边界的情况下,如果符合微服务拆分原则,也可以考虑将应用层与领域层代码合并为一个微服务部署。
对于企业级多中台应用,多个中台应用通过 API 网关对外发布 API 服务。核心域业务中台在调用支撑域和通用域中台服务时通过核心域应用层完成多中台服务的组合和编排,为前台应用提供 API 服务。核心域中台的应用层是否独立成微服务部署,需考虑的情况与单应用系统相似。
五、总结
分层架构的一个重要原则是每层只能与位于其下方的层发生依赖。它的好处是显而易见的:
首先,由于层间松散的耦合关系,使得我们可以专注于本层的设计,而不必关心其他层的设计,也不必担心自己的设计会影响其它层,对提高软件质量大有裨益。其次,分层架构使得程序结构清晰,升级和维护都变得十分容易,更改某层的代码,只要本层的接口保持稳定,其他层可以不必修改。即使本层的接口发生变化,也只影响相邻的上层,修改工作量小且错误可以控制,不会带来意外的风险。