天天看点

领域驱动设计(DDD)之分层架构

前言

由于由近几年微服务架构兴起,领域驱动设计(DDD)也被大多领域专家重新看待。但是其实这两者本来是不相关的两个东西,2004年著名建模专家Eric Evans发表了他最影响力的书籍《领域驱动设计》,提了现在如日中天的架构设计方法论 — 领域驱动设计,核心思想是通过领域驱动设计方法定义领域模型,从而确定业务和应用边界,保证业务模型与代码模型的一致性。而微服务2014年横空出世,由 Thoughworks 首席科学家 Martin Flower提出,微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作

领域驱动设计更加强调的是一个架构设计方法论,所谓方法论的东西都是比较抽象并且很意识化,就像是建议你怎么做,但不会可能觉得你做并做对了,但是在别人的认知上,你可能没做,或者做的东西在认知水平上存在差异。而微服务是一种SOA演进的面向服务的系统架构,注重业务的垂直划分,达到服务之间的职责单一明确。然而通过DDD 事件风暴、四色建模等得到的领域模型,模型上线文的边界其实和微服务的边界大体符合。甚至可以这么说,采用 DDD 方法建立的领域模型,更能清晰地划分微服务的逻辑边界和物理边界,好的领域驱动设计也就直接关系到微服务设计的水平,这就为什么微服务设计很多时候都是选择DDD。所以领域驱动设计在微服务火起来的这几年被重新认知,并有了很多结合微服务设计的DDD的系统落地。

由于DDD设计的理念偏广,DDD名词概念,DDD与微服务落地,DDD事件风暴及领域建模,DDD大中台实践,DDD与领域模型一致性等等话题,笔者这里就DDD分层架构展开梳理,当然相应的其他模块的知识有机会也会补上的

领域模型一旦确定,开发者都不期望代码脱离模型分析确立的初衷。软件维护的核心问题是软件设计的完整性概念的维护,软件变得难以维护的根本原因,在于模型概念完整性在软件生命周期被破坏,并脱离分析模型的结果。在面向对象的程序中,有时候为了可以容易将事情快速工作,用户界面、数据库逻辑以及其他聚合加工等代码经常被直接写在对象实体中。当领域相关逻辑被嵌入其它层,阅读和维护这些代码变得举步艰难。表面上只是改用户界面层的逻辑,却变成了领域逻辑的调整。对业务的变更需要跟踪从用户界面,业务逻辑,甚至是数据库层的逻辑,在某一处对代码的简单修改,都可能造成难以预测和不符合希望的结果,软件细节调整需要大面积的软件测试回归,自动化测试变得更加繁琐,难以进行。

所以,需要对一个复杂的程序进行层次划分,每一个层次内部进行内聚,单个层次依赖底下层次,解耦层次之间的业务逻辑交叉。将领域相关逻辑代码聚集到某一层,用户界面和数据库等第三依赖组件隔离开来,领域相关操作只关心内部领域相关逻辑的实现,不再关注如何展示自己,如何保存自己,如何同步自己,如何解释用户命令等细节性工作。这会让一个领域模型更加清晰,调整会回溯的成本随着分层的合理性逐渐降低

传统三层架构

互联网早期,业务系统诉求相对简单,很多时候CRUD已经满足大部分场景,很多时候都不需要考虑并发,也不用估计业务快速发展带来的系统复杂度和维护成本增加。传统企业应用大多是单体架构,而三层架构成为单体架构的一种常态。三层架构解决了程序内代码间调用复杂、代码职责不清的问题,但这种分层是逻辑概念,在物理上它是中心化的集中式架构,并不适合分布式微服务架构。

领域驱动设计(DDD)之分层架构

三层架构

层次解析

DDD四层架构

领域驱动设计(DDD)之分层架构

四层架构

事务管理比较有歧义,但是笔者还是将他放在应用层,当然,在

层次解析

 依赖倒置

三层架构如何演变四层?

DDD五层架构(DCI)

领域驱动设计(DDD)之分层架构

五层架构

六边形架构

严格分层 VS 松散分层

看完上面的分层架构,你应该能很清楚的知道DDD在架构设计上的分层形式,笔者画的图很明显可以看出架构层级依赖的单向性,也就是从上级层次到夏季层次。其实,领域驱动设计发展的过程中,也产生了一些依赖上的分歧:严格分层架构和松散分层架构。

在严格分层架构中,任何层只能与位于其直接下方的层发生依赖。在松散分层架构中,任何层可以与其任意下方的层发生依赖。这里你应该可以理解,DDD 分层架构模型其实属于严格分层架构,任何层只能对位于其直接下方的层产生依赖。而传统的 DDD 分层架构更多的是属于松散分层架构,允许某层与下方其任意层发生依赖。

时延性可能比较差 --》 松散分层

服务依赖关系,管理和维护 --》 严格分层

也严格分层 松散分层差别

优缺点及挑选,笔者认为

实现领域驱动设计在分层架构上更加强调 “每层只能与位于其下方的层发生耦合”,

为何DDD架构分层如此重要

番外:充血模型 VS 贫血模型

后记

最后还是有一些需要强调,可能你会很疑惑,从领域建模到微服务建设,到最后你落地时候发现,你定义的领域层成为别人眼中的应用层,定义的应用层成为别人看到的领域层。当然,这是完全有可能的,你看到的视觉是和你所从事的业务,负责的职责有关系,你们所看到的核心域、通用域和基础域是完全不一样的。比如你是负责订单业务模块,那么订单就是你的核心域,而用户的账户相关业务相对你来说就是通用域。而反过来相对账户模块的同学而言,他们设计系统对账相关,总是需要检索账户对应的所有订单数据,达到用户账户数据一致性,而你所在的订单模块也就成为了账户模块同学眼中的领域层了

此外,也并没有哪一种分层架构是最优秀的,分层架构大到公司整体系统架构,小到代码层次,都可以通过DDD领域建模,划分领域上线文,建立领域内通用语言,面对不同的业务场景,团队,文化,管理等因素,需要考虑的问题也就有所差别。选择分层架构的时候,应该尽可能的从不同应用场景出发,选择合适的架构分层

同时,领域模型不是一成不变的,因为业务的变化会影响领域模型,而领域模型的变化则会影响微服务的功能和边界。随着业务发展,聚合重组和拆分会是一种常态。原来领域层的聚合,可能成为应用程的业务控制模块,业务控制模块随着限界上下文重新划分,进入领域层。架构演进是一种动态迭代,并快速变化的过程,每个时刻,你看到的都是当时的业务系统的快照。

===

待续,待补充

===

继续阅读