天天看点

领域驱动设计 -- 最快学习路径介绍

从战略入门

这种方式相对比第一种方法,费时很多,需要很大的毅力坚持,但因为是在实践中不断成长的,最终是可以形成自己的方法论的。但耗时太慢长,我自己不断实践落地 DDD 近 5 年,才形成了自己一丢丢的方法论。

接下来给大家提供一些总结的资料,供大家入门学习:

  1. 实体、聚合、值对象、聚合、工厂、仓储、领域服务等领域模型的基础概念,尽量白话准确;
  2. 提供了挖掘通用语言的两种方法,指导如何从需求文章中快速的挖掘通用语言;
  3. 提供一个领域模型图 Demo,大家可以选取自己工作中最熟悉的业务,画一画;
  4. 选取了两个角度,描述下如何写出业务高内聚的 DDD 代码。

大家可以按照 1、2、3、4 的步骤来试一试,这个学习路径,最关键的点在于敢于实战,在失败中总结经验,如果你只是看看、不动手,不敢于失败很多次的话,建议还是学习第一种方法吧。

实体

实体是具有唯一标识的,可以表示业务连续性变化的领域元素。

唯一标识很好理解,就像人的身份证一样,不管人的年龄如何变化,住宅地址如何变化,你的身份证都是不变的,唯一标识一直能够在实体变化过程中辨别实体。

业务连续性变化的理解,我们拆分成两个:

  • 如何知道业务发生了变化
  • 业务连续性变化

如何知道业务发生了变化:如果当前业务变化已经导致实体的属性发生变化,那么当前业务就已经发生变化了。

我们举个例子:比如你在淘宝买东西,下单之后会生成一个订单实体,在之后的任意时刻,只要订单实体的属性发生了变动,就表明当前订单业务发生了变化。

比如订单实体有个属性,叫做订单状态,订单刚生成的时候,是支付成功待发货状态,然后商家操作了发货,订单的状态就会变成已发货,那么此时订单的状态从待发货变成了已发货,订单的属性发生了变化,即业务发生了变化。

业务连续性变化:实体属性的变化在时间上有跨度,我们称为业务有连续性变化。

比如说订单状态从已发货,又变更成了订单完成,这里订单状态的变化,在时间上是有一定的跨度的,就是说当前业务有连续性的变化。

以上两种说明是为了让大家更好的理解,只针对实体而言,因为业务这个词的范畴太大了,很难定义业务是什么,但在实体的范畴内,业务的变化可以直接体现在实体属性的变化上。

值对象

定义:值对象是对事物的描述,更确切的说,就是对领域对象的描述。

比如说下单场景中,我们会记录下单的来源信息,比如说订单是 H5 下单,还是 App 下单?下单的 IP 地址是多少?下单的手机型号又是什么?这些来源信息就是对订单实体的一种描述,我们可以叫做值对象。

既然是对实体的一种描述,那么描述一旦产生,大多数情况下都是已经发生了的事情,就是死的,不会在更改了,这也是值对象的一大特性。

聚合

把领域对象聚合在一起,并维护领域对象之间的关系,我在一篇免费文章上详细地说过,说的很明白,链接:

https://dwz.cn/XZ9HCMqy

工厂

工厂比较简单,主要是用来干两件事情,新建对象和重塑对象。 当实体、聚合、值对象的创建逻辑比较复杂的时候,我们就可以使用工厂进行创建。

重塑对象的例子:

我们在和外部公司进行对接的时候,大多数会通过 HTTPS 接口进行远程调用,这时我们接受到返回的参数,很可能是个 JSON 格式,因为依赖不了外部公司的 API 包,JSON 就不能反序列化成一个 DTO,这时候 JSON 转化成可使用的对象就比较复杂。我们可以把复杂的转化工作交给工厂,工厂此时的作用就是把 JSON 格式转化成可直接使用的对象。这种场景在对接基金保险公司时特别常见,基金保险公司的外部接口往往很复杂,字段非常多,这时候转化工作就很繁琐,利用工厂进行转化会很合适。

仓储

Repository 是用来做对象的储存和访问的,作用是让大家始终聚焦领域模型。

对象的存储和访问大家应该都清楚,就是增删改查,这个大家都会,这个也不是仓储的重点。

仓储的重点在于如何让大家始终聚焦领域模型,在实际工作中,大家写代码的时候,都是一张表一个仓储,这是不对的,仓库的定义应该从业务出发,而不应该去适配表结构。

领域服务

领域服务是一个动作,当动作挂不到领域对象上时(动作不是领域能力的时候),我们就把它叫做领域服务。

以上就是 DDD 领域层常见的领域元素,然后我又画了一张落地思路图:

领域驱动设计 -- 最快学习路径介绍

这位同学也时常和我沟通,突然有一天,丢了一个领域模型图给我,我看了下,觉得画的很好,算是战略入门了,从这个同学身上我还发现另外一种特质:敢于动手。

很多同学学习 DDD 丝毫不敢动手,或者说懒于动手,懒得整理通用语言,懒得画领域模型图,只靠眼睛看,看是永远都学不会 DDD,也落地不了 DDD 的。

领域模型

领域模型对业务的一种抽象,领域模型图就是业务的抽象表达,好的领域模型图往往能让你事半功倍,提供一个领域模型图模版给大家:

领域驱动设计 -- 最快学习路径介绍

这个领域模型图用不同形状 + 不同颜色,代表了 6 种领域元素,用不同箭头形状代表了领域元素之间的逻辑关系,在我们实际工作中已经够用了,领域模型图大家能看懂就行,易懂的同时在加上好看那就更好了,至今为止,没有见过比这个好看易懂的领域模型图了。

那么领域模型图来自何处呢?来自通用语言。

在画领域模型图之前,我们必须要把通用语言整理出来,然后再把通用语言转化成领域模型图,在通用语言转化领域模型的过程中,应该根据领域元素的定义来进行划分,完全可以一一对应。

如何挖掘通用语言?

首先大家要清楚什么是通用语言。

通用语言的基础定义:一定上下文内,对业务概念的一致通用表达。直白来说,就是团队内部成员,在同一个上下文内,对同一个业务概念的理解是一致的。

但很多人往往看不到通用语言的深层含义:理清业务是什么,能干什么,以及和其他业务边界的过程。

在领域建模时,最重要的就是通用语言的梳理了,一般我会花一半的时间放到通用语言的建立上,在整理通用语言的过程中,我们会去想很多:领域的定义?领域的能力?领域的边界?……

挖掘通用语言我自己有两种办法:

  1. 抓住名词,联想动词:这种办法特别简单,可以快速帮助我们把需求场景想全。
  2. WR 原则:在九十年代的时候,有人提出了 5W1H 分析法,来帮助人们快速地理解问题和解决问题,其目标是为了快速地弄明白问题。下图就是 5W1H 分析法的图解:
领域驱动设计 -- 最快学习路径介绍

截图来自百度百科。5W1H 法体现了一种分析过程,但落地的时候,这种过程不重要,分析的结果却特别重要。比如说你在淘宝下单,得到订单;发货,得到发货单;退款,得到退款单,你可以用 5W1H 分析下单、发货和退款的过程,但领域建模时,你关注的却是订单、发货单和退款单三种结果,所以说分析的结果特别重要,我们在 5W1H 的基础上加了一个结果 Result,简读就是 WR 原则。

DDD

继续阅读