DDD 领域驱动设计落地实践系列:战略设计和战术设计(一)
引言
通过前面的文章介绍,相信大家对于什么是 DDD 有了初步的了解,知道它是一种微服务的架构设计方法论,为我们解决如何建立领域模型,如何实现微服务划分等提供了方向和指导。但是对于如何具体落地使用 DDD,可能大家还是一脸懵 B 的状态,因此从本文开始以及后面的文章将对如何进行 DDD 落地进行详细的阐述。在这其中还是会涉及到 DDD 中的一些重要概念,原本想着在一篇文章中介绍所有的概念,但是我觉得,概念总是在它该出现的时候出现才会让大家印象深刻,否则这些概念只是死板的概念,我们不清楚他为什么出现以及可以解决什么问题。
DDD大致过程
如下图所示,实现 DDD 落地大致需要经历这样三个阶段,即为业务分析-》战略设计-》战术设计,不同阶段的输出都是下一阶段的输入。业务分析阶段为战略设计输出经过统一语言描述的业务事件、业务逻辑以及业务分类,而战略设计阶段又为战术设计阶段输入领域模型以及边界上下文,方便其进行微服务拆分以及模型映射。下面我们分别看下这三个阶段到底都做了什么事情。
业务分析:在这个阶段需要集齐项目团队的成员主要包括领域专家、设计人员、开发人员等一起对业务问题域以及业务期望进行全面的梳理,厘请业务中的统一语言,在业务领域中发现领域事件、领域对象及其对应的领域行为,搞清楚他们各自的关联关系。
战略设计:通过 DDD 的理论,对业务进行领域划分构建领域模型,梳理出相应的限界上下文,通过统一的领域语言从战略层面进行领域划分以及构建领域模型。在构建领域模型的过程中需要梳理出对应的聚合、实体、以及值对象。
战术设计:以领域模型为战术设计的输入,以限界上下文作为微服务划分的边界进行微服务拆分,在每个微服务中进行领域分层,实现领域模型对于代码的映射,从而实现 DDD 的真正落地实施。
DDD大致过相关概念补充
在介绍战略设计和战术设计之前,我们先来弄清楚一些晦涩难懂的概念性的内容,这些概念看上去总是不明觉厉。我觉得 DDD 不容易入门的一个原因就是这些概念太不好理解了,即便是《领域驱动设计:软件核心复杂性应对之道》原著中的描述更加让人难以捉摸。要想理解这些概念性的内容,我们要思考为什么有这样的概念,以及它的出现是为了解决什么问题,在实际的上下文场景下是怎么运用的,我想只有这样我们对这些不明觉厉的东东才能有更加深刻的理解。我尽量结合一些实例来进行说明,方便大家的理解。
1、值对象
值对象看上去又是比较抽象的概念,越抽象的概念我们越要抓住最主要的脉络,才能理解。就值对象来说,我们可以把他理解没有 ID 的东东,什么叫没有 ID 呢?可以这么理解,当我们在外面吃饭的时候,在餐厅里面选位子落座,我们会关心这个桌子是哪里生成的,编码是什么以及规格是怎样的吗?显然不会,有空位坐就可以了。当然我们还是需要关注值对象上下文的,如刚才的例子,我们消费者并不关心坐哪个位子,但是商家是关心的,因为他要根据桌号来进行上菜以及收账。
再来举一个例子,在我们设计用户信息的时候,这其中就会包括用户的地址,用户的地址实际是由这个用户是哪个省的,哪个市的,哪个县的以及具体地址是什么、邮编是什么等等属性信息组成,那么这个地址信息在用户信息中实际就是一个值对象,他不需要唯一的 ID 来标识。
2、实体
和值对象不同的是,实体是有唯一标识的,这就好比我们每个人都会有身份证,身份证上面的身份证号码就是每个人的唯一标识。另外这个身份证号码会一直跟着我们不会改变,即使你改了名字户口状态变化,但是身份证号码是不会变化的,这也是实体的另一个特征就是它具有延续性。实体对应了业务对象的业务属性以及业务行为。
值对象以及实体都是领域模型中的领域对象,是组成领域模型的基础元素,一起实现领域内的最基本的核心领域逻辑。
3、聚合
又是一个看上去不好理解的概念,实际上用大白话来说,如果人是一个个不同的业务实体,那么社会中的不同组织、机构就是将对应技能的人聚集在一起发挥更大的业务价值以及完成更加复杂的业务行为的的集合。这就好比我们公司里面有种各样的部门,有人力部门负责招聘和薪酬、有销售部门负责营销、有研发部门负责产品研发。不同的部门实际就是不同的聚合。聚合就是有业务关联关系的实体以及值对象的集合,通过实体、值对象以及各自之间的业务逻辑聚合在一起完成某个业务节点,我们就可以理解为聚合。我们可以根据业务的单一职责以及高内聚的的设计原来来进行聚合的划分。
4、聚合根
聚合的出现实际是一种业务单元,那它必定涉及到数据的持久化,如果在聚合中的任意实体都可以被外部进行数据修改,那么我们将很难保证聚合内的数据一致性。因此我们需要有一个数据输入修改的统一入口来保证聚合内的数据修改统一的符合聚合中的业务规则,因此出现了聚合根的概念。聚合根实际是就是一种实体,具备唯一标识,有独立的生命周期。但是他是特殊的实体,他有协调实体以及值对象完成业务逻辑的功能,好比是一个部门的负责人一样。一个聚合只有一个聚合根,聚合根在聚合之内采用引用依赖的方式对实体和值对象进行组织和协调,聚合根和聚合根之间通过唯一 id 进行聚合之间的协同。
战略设计
战略设计这四个字听起来有点高大上的感觉,感觉离我等 DS 比较远。实际上无论对于公司或者个人来说,都需要有个发展的目标以及指导方针,指引我们该向何方前进,这个指导性的内容,我们就可以称之为战略。那么在 DDD 领域,战略设计主要从业务角度出发,划分业务的领域边界,建立基于通用语言和业务上下文语义边界的限界上下文,实现业务领域模型的构建。使得限界上下文可以作为微服务拆分和设计的边界。因为必须先有边界清晰的领域模型以及上下文,我们才能设计出边界清晰的微服务。因此在战略设计阶段最重要的就是限界上下文以及领域建模。
通常在业务分析阶段我们把业务域的主体流程进行了梳理以及分析,同事将业务期望进行了定义。在进行战略设计的过程中,需要对业务领域进行全面的梳理,首先对业务进行领域切分,划分出业务的上下文边界,然后建立对应的限界上文中的领域模型,上下文边界和领域模型可以做诶微服务拆分拆分设计的输入,指导微服务落地时的拆分设计。其中业务中,对应的领域模型十分重要。那么我们该采用什么方法才能从复杂的业务领域中构建出高内聚低耦合的领域模型呢?我们可以通过业务分析以及领域建模两个阶段来实现领域模型的构建。
文章转自公众号:慕枫技术笔记