DDD 分层架构

DDD 学习笔记 | 极客时间 | 手把手教你落地 DDD

🏆 原文:09|分层架构:怎样逃离“大泥球”?

六边形架构

解决怎样保证代码与模型一致的问题,这个问题又分成两个层面

  • 第一个层面是要有一个合理的代码架构
  • 第二个层面是更详细的代码编写

分层架构的圈层结构图

分层架构把代码分成若干层,每层负责不同的关注点。 图里的箭头表示依赖关系,这里的意思是只能外层依赖内层,内层不能依赖外层。

这背后其实是根据软件架构中的一个重要原则:代码中不稳定的部分,应该依赖稳定的部分。所以,分层架构中越是内层,就越稳定,越是外层,相对就越容易变化。

分离领域

DDD 对代码架构最核心的要求就是要将领域层分离出来

领域层示意图

给领域一个“门面”

领域层封装的逻辑通常是细粒度的,并不适合直接作为 API 暴露给外部。另外,还有一些不属于领域层的横切关注点,比如像事务控制,应该单独处理。 所以,我们往往要在领域层外面再加一层,DDD 和六边形架构都将这一层称为 Application,也就是应用层。

领域 + 应用层示意图

Application 层主要负责的逻辑

  1. 接受来自客户端的请求,调用和协调领域层的逻辑来解决问题;

  2. 将领域层的处理结果封装为更简单的粗粒度对象,作为对外 API 的参数。这里说的粗粒度对象一般是 DTO(Data Transfer Object),也就是没有逻辑的数据传输对象,应用层负责 DTO 和领域对象的数据转换;

  3. 负责处理事务、日志、权限等等横切关注点。从设计模式的角度,这一层相当于“门面”(Facade)模式,如果你想更深入地了解这个模式,可以读一下相关书籍,例如 《Head First 设计模式》。

应用层本身并不包含领域逻辑,而是对领域层中的逻辑进行封装和编排。我们不妨把应用层的逻辑称为应用逻辑

封装应用逻辑的类通常没有状态,只有方法,一般称为应用服务,我们可以用 XxxService 的形式来命名。

Adapter 层处理输入输出

这一层的目的是把业务功能“适配”到不同的输入输出技术。

适配器会把和具体技术有关的请求,翻译成和技术无关的请求,再调用应用层来实现业务功能;在接收到应用层的返回值以后,又转化成技术相关的响应,返回给外界。 也就是说适配器层屏蔽了输入输出技术的差异,从而使应用层与具体技术无关,这样就达到了分离关注点的目的。

在六边形架构里,把由外向内的适配器叫做 driving adapter,我把它译作主动适配器;而由内向外的适配器叫做 driven adapter,可以译作被动适配器。
准确地说,被动适配器的作用不限于访问数据库,而是访问所有外部资源。

这里的 Adapter 感觉就是 Anticorruption Layer(防腐层)

用“适配器”处理数据持久化

主动适配器被动适配器
英文名Driving AdapterDriven Adapter
定义描述由外向内调用由内向外调用
组件举例ControllerRepository(仓库)
场景举例HTTP 客户端调用系统系统调用数据库

common 层存放通用工具和框架

通用工具、对 Spring 框架进行的封装、自己的小框架,这些框架性的代码可能用于上面说的任何一层。

虽然这些代码可能被前面的所有层依赖,但它和上面说的各层不在同一个纬度

它们是对各层代码起到公共的支撑作用的

common 包下两个子包的说明

  • framework 存放框架性的代码
  • util 存放工具性的代码

框架和工具的一般区别

  • 框架会调用我们自己写的代码
  • 工具则被我们写的代码所调用

练习源码

comments powered by Disqus