【领域驱动设计】(4):从 DDD 落实到数据库设计的整个过程

云世  公众号

过去,系统的软件设计是以数据库设计为核心,当需求确定下来以后,团队首先开始进行数据库设计。因为数据库是各个模块唯一的接口,当整个团队将数据库设计确定下来以后,就可以按照模块各自独立地进行开发了。在上面的过程中,为了提高团队开发速度,尽量让各个模块不要交互,从而达到各自独立开发的效果。但是,随着系统规模越来越大,业务逻辑越来越复杂,我们越来越难于保证各个模块独立不交互了。

在进入DDD的数据库设计落地之前,先了解DDD基于微服务的基本设计理念:

DDD基于微服务的概念理解

什么是DDD?

DDD不是一种架构风格,而是一种方法论。什么是方法论,每个人按照自己的想法来设计就是一套方法论;DDD是一种业务比较认可,对于微服务拆分的一种方法论。

为什么在微服务的大环境下DDD才流行?

  • 微服务区别于系统,服务是一组想对较小且独立功能单元,是用户感知最小功能集。

  • DDD计的模型中具有边界的最小原子是聚合,聚合和聚合之间由于只通过聚合根进行关联,所以当需要把一个聚合根从一个限界上下文移动到另外一个限界上下文的时候,非常低的移动成本可以很容易地对微服务进行重构。

  • 微服务和DDD的理念不谋而合,在微服务的大环境下DDD的流行是趋势。

为什么很多行业在微服务的架构上还是MVC架构?

  • 固化思维,从学校到工作,从学习到开源架构都是采取这种MVC架构;

  • 很多行业是基于传统行业进行项目改造,只是中间件用了微服务相关,但是业务没有明显的拆分依据,换汤不换药;

  • 资源成本,基于DDD的拆分成本比较高,主要体现在事件风暴、领域划分、实体聚合,上下文边界确定;

  • 对于企业来说,一个人能搞定的,不需要花大量的人力,时间去做规划;

  • 三层架构属于贫血模型,虽然不符合面向对象编程思想,架构结构比较简单,上手容易。

从技术上来讲DDD和MVC有什么区别?

MVC和DDD主要的区别在Service层,主要区别:

  • MVC:Service 实现全量业务逻辑,BO(Business Object)保存业务对象,属于贫血模型;

  • DDD:Service 实现少量业务逻辑,DO(Domain Object) 包含聚合跟、聚合、实体、值对象,从技术上来看就是实体,里面有相关领域的行为、动作、属性、依赖关系,属性充血模型。

DDD的基础概念

  • 领域:领域是DDD中最大的概念,主要确定边界范围,领域又分为核心域(核心业务逻辑)、通用域(公共业务逻辑)、支撑域(基础第三方业务逻辑);

  • 界限上下文:在界限上下文中要建立通用语言,望文生义,就是大家都看得到,认可的叫法就是通用语言;界限上下文主要是来确定领域边界;

  • 聚合根:聚合根式一个根实体,里面包含了许多聚合,而且该聚合根有唯一标识,可以协调里面的每个聚合,外部访问只能根据聚合根的唯一标识进行访问里面的私有内容;

  • 聚合:聚合是一个整体,把所有的实体和值对象组织起来,做到一个聚合的作用,确保领域在执行逻辑的时候,确定数据一致性,从设计上避免数据不一致性;

  • 实体:整体概念的多个属性归集到的属性集合,有唯一标识id,实体是实实在在的业务对象,具有业务属性、行为和业务逻辑;

  • 值对象:若干个属性的集合,只有数据初始化操作和有限的不涉及修改数据的行为,不包含业务逻辑

⚠️DDD建模过程

  • 采用风暴事件,根据句业务行为,找过过程中发生行为的实体和值对象;

  • 在众多实体中选出合适的作为聚合根,挑选依据主要是否有独立的生命周期和全局唯一的ID,是否可以修改或创建其它对象;

  • 根据业务单一职责和高内聚原则,找出于聚合根关联的实体和值对象;

  • 在聚合内根据聚合根、实体、值对象,画出对象引用模型和依赖关系模型;

  • 多个聚合根据业务语义和上下文划分到一个上下文界面,也就是一个小的微服务。

怎么理解领域、子域、核心域、通用域和支撑域

DDD 的领域就是边界内要解决的业务问题域。

  • 我们把划分出来的多个子领域称为子域,每个子域对应一个更小的问题域或更小的业务范围。

  • 领域的核心思想就是将问题域逐级细分,来降低业务理解和系统实现的复杂度。通过领域细分,逐步缩小微服务需要解决的问题域,构建合适的领域模型,而领域模型映射成系统就是微服务了

  • 核心域、支撑域和通用域的主要目标是:通过领域划分,区分不同子域在公司内的不同功能属性和重要性,从而公司可对不同子域采取不同的资源投入和建设策略,其关注度也会不一样。

怎么界定上下文

  • 在事件风暴过程中,通过团队交流达成共识的,能够简单、清晰、准确描述业务涵义和规则的语言就是通用语言

  • DDD 在战略设计上提出了“限界上下文”这个 概念,用来确定语义所在的领域边界。

  • 通用语言:团队内部能够清晰、准确的描述业务模型的语言就是通用语言

  • 限界上下文:为通用语言划定边界,并提供语义上下文。领域内所有界限上下文的模型构成了整个领域模型。理论上,某些条件下,限界上下文的划分也最终确定了微服务的边界。

什么是实体和值对象

  • 实体有唯一ID,实体是通过ID来区分不同实体的。即使实体的属性都发生了改变,只要它的ID还是原来的ID,实体还是那个实体。

  • 值对象是通过属性来区分不同值对象的,值对象只要改变了属性值,就已经不是原来的值对象了。

  • 在领域建模时,我们可以将部分对象设计为值对象,保留对象的业务涵义,同时又减少了实体的数量;

  • 在数据建模时,我们可以将值对象嵌入实体,减少实体表的数量,简化数据库设计。

怎么理解聚合和聚合根

  • 领域模型内的实体和值对象就好比个体,而能让实体和值对象协同工作的组织就是聚合,它用来确保这些领域对象在实现共同的业务逻辑时,能保证数据的一致性。

  • 你可以这么理解,聚合就是由业务和逻辑紧密关联的实体和值对象组合而成的,聚合是数据修改和持久化的基本单元,每一个聚合对应一个仓储,实现数据的持久化

  • 判断一个实体是否是聚合根,你可以结合以下场景分析:

    是否有独立的生命周期?是否有全局唯一 ID? 是否可以创建或修改其它对象?是否有专门的模块来管这个实体?

总结:

  • 聚合的特点: 高内聚、低耦合,它是领域模型中最底层的边界,可以作为拆分微服务的最小单位,但不建议你对微服务过度拆分。在对性能有极致要求的场景中,聚合可以独立作为一个微服务,以满足版本的高频发布和极致的弹性伸缩能力。

    一个微服务可以包含多个聚合,聚合之间的边界是微服务内天然的逻辑边界。有了这个逻辑边界,在微服务架构演进时就可以以聚合为单位进行拆分和组合了,微服务的架构演进也就不再是一件难事了。

  • 聚合根的特点: 聚合根是实体,有实体的特点,具有全局唯一标识,有独立的生命周期。一个聚合只有一个聚合根,聚合根在聚合内对实体和值对象采用直接对象引用的方式进行组织 和协调,聚合根与聚合根之间通过 ID 关联的方式实现聚合之间的协同。

  • 实体的特点: 有 ID 标识,通过 ID 判断相等性,ID 在聚合内唯一即可。状态可变,它依附于聚合根,其生命周期由聚合根管理。实体一般会持久化,但与数据库持久化对象不一定是 一对一的关系。实体可以引用聚合内

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云世

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值