领域驱动架构演进之路

121 阅读6分钟

现有的DDD架构有六边形架构、洋葱架构、命令查询职责分离架构、整洁架构、菱形架构、清晰架构、COLA架构、分层架构。

 

那演进关系是怎样的呢?

忽略时间线看领域驱动模型发展的三个阶段

  一、最基础的:简单的分层分类以及单箭头的依赖关系 

六边形架构,六边形架构又称为“端口-适配器”架构,它将系统分为内部和外部,内部代表了应用的业务逻辑,外部代表应用的驱动逻辑、基础设施或其他应用。  

命令查询职责分离架构(CQRS-ES),CQRS - Command Query Responsibility Segregation,故名思义,将系统中的操作分为两类,即「命令」(Command) 与「查询」(Query)。命令则是对会引起数据状态发生变化的操作的总称,即我们常说的新增,更新,删除这些操作。而查询指的是不会对数据产生变化的操作,只是按照某些条件查找数据。  

分层架构:DDD传统的分层架构为四层架构,从interface、application、domain、infrastructure四层从上到下,上层可以直接调用下层。  

在分层架构里面,并没有涉及复杂数据查询问题,此问题不涉及业务逻辑处理所以不应该放在领域层处理。如果复杂数据查询需求较多可采用CQRS模式,将查询单独一个模块处理。如果较少可由基础设施层做数据查询,应用层做数据封装,用户接口层做数据调用,在大数据大并发情况下,多表关联会严重影响数据库性能,可以考虑做宽表查询。

  他们的共同特点是进行了分层和分类,但是他们的依赖关系都是单向的。

  二、更进一步的:分层分类+依赖倒置  

洋葱架构是在六边形架构的基础之上将内层做了进一步的划分,且明确了依赖方向。一个典型的洋葱架构分层分包方式和依赖关系如下,外层依赖内层,内层不感知外层,在不破坏依赖方向的前提下,外层亦可以直接调用任一内层。

(1)Adapters:适配器层,包含user interface、infrastructure和test等。

(2)Application Services:应用服务层,主要包含应用程序的入口、出口、仓储等。

(3)Domain Services:领域服务层,涉及跨实体的业务逻辑放在此处。

(4)Domain Model:核心的领域模型,对应DDD里面的实体、值对象、工厂等等。  

外层直接调用任一内层,那用户接口层就有机会直接调用核心的领域模型,核心的领域模型是不应该直接暴露给用户的。  

  三、融合:分层的同时开始限定各层的依赖关系。  

整洁架构:整洁架构将六边形架构、洋葱架构等整合成一个可以实际落地的架构。代码依赖只能由外向内。越向内,抽象程度越高,越向外,细节信息越多。  

清晰架构:根据六边形、洋葱、整洁和CQRS等架构融合而来。  

COLA4.0 是Clean Object-Oriented and Layered Architecture的缩写,代表“整洁面向对象分层架构”,官方对COLA架构定义了严格的分层模式,因此COLA架构不仅仅是架构设计方法论,还是一整套代码架构,拿来即用。  

解析一下COLA的名字,“整洁”的面向对象的“分层结构”,“整洁”是整洁架构,“分层结构”是分层架构,那这里可以这样认为,COLA4.0的依赖关系是整洁架构的依赖思想,外层如基础设施层会依赖内层领域层,形式上是分层架构的形式,每一层都有他自己的明确功能。  

COLA4.0中的应用层直接依赖基础设施层,那应用层就和基础设施曾耦合了,这里背离了洋葱可剥离的本质,当你试图替换基础设施层时,会涉及到对服务层的修改。

  现阶段的总结:  

简单的分层分类以及单箭头的依赖关系 -> 分层分类+依赖倒置 -> 融合:分层的同时开始限定各层的依赖关系。  

之前做研究的时候会觉得引言是非常鸡肋的存在,有一些文献是非常核心的参考文献,还有一些文献其实是凑字数的,引言部分表面上是梳理发展脉络,实质上是为了诱使读者达成共识。但是,一切被普遍验证过的东西确实有用,只是当时体会不到。   比如,梳理领域驱动的架构演进变化,可以从中抽象出演进的方向,对未来的发展方向也会有启发。  

现在可能的发展思路就是对分层分类的优化,以及对各层次间依赖关系的优化,框架是为了限制程序的控制权。  

代码实践中的基本思想

分类: 操作的分类:修改实体状态(增删改)/未修改实体状态(查)

逻辑分类:技术逻辑和业务逻辑,业务逻辑和技术逻辑还可以继续进行划分

模型分类:数据模型和领域模型

有无生命周期的分类:有单独的生命周期,没有单独的生命周期  

分层: 分层其实也是一种分类,将系统按功能不同分层。  

分层和分类的结合,程序会变成网状结构,寻找一个功能它的坐标是多维的,根据(层,模块,功能)的坐标可以快速定位,  

控制反转:整体的实现流程是一种控制反转。“控制反转”指的是对程序执行流程的控制,而“反转”指的是在没有使用框架之前,程序员自己控制整个程序的执行。在使用框架之后,整个程序的执行流程通过框架来控制。流程的控制权从程序员“反转”给了框架。  

依赖倒置:依赖抽象接口而不是依赖具体实现细节,实现了面向接口编程的愿景,可以很方便地替换同一接口的不同实现,而不会影响到依赖这个接口的服务。   语义显示化,代码模型化,最终实现业务代码即业务模型。  

好处

这样做的好处:解耦、内聚、防腐、最小化修改影响范围  

内聚和解耦本身就是目的,实现了内聚和解耦之后,可以最小化修改逻辑的影响范围。避免小变更大改动。局部逻辑修改的影响范围不会扩散到整体。