二、演练领域驱动的设计过程

一、业务分析:统一语言与事件风暴

1、统一语言:

客户明白自己的领域知识也就是业务,以及自己需要解决的问题,也叫做痛点,但是不知道技术。技术人员知道技术,但是不了解客户的业务。所以两者交流起来往往会有很多出入,技术人员和客户交流的过程中要去不断建立一种双方都认可的关键词,来深化领域知识,使得领域模型的建立。

2、事件风暴:

一种基于工作坊的事件方法,它可以快速发现业务领域中正在发生的事件,知道领域建模及程序方法。基本思想是将软件开发人员与领域专家(客户)在一起,相互学习。让领域专家更加理解

①领域事件:即领域中发生的事实(过去发生的事实)(fact)

在真实世界中,当满足某个条件的时候,某个发起者会触发某个事件,做某件事情。

②事实(fact):已经发生,很重要

是指哪些过去已经发生过的事件。
鉴于过去已经发生的事件不会发生改变。
建设信息化系统的实质就是:将过去已经发生的事实,存储到数据库中。从而提高管理水平,效率。

③事件风暴会议:

Ⅰ、目标:以完成领域模型的创建
Ⅱ、参会人员:领域专家和软件开发人员
Ⅲ、会议以探讨领域事件开始,从前往后一次梳理,以确保领域中所有事件能够覆盖。
Ⅳ、项目组成语不断增加各种命令和事件,进而思考与之相关的资源,外部系统与时间。
Ⅴ、在分析过程中的人和事相互之间的关系以箭头方式标识,分析有没有聚合关系,如果存在聚合关系,用紫色的便签纸标注出来。
Ⅵ、将模型分配到各个限界上下文中,构建上下文地图。

④案例:在线订餐系统

在这里插入图片描述

Ⅰ、梳理流程,识别领域事件(当达到某个条件,某个发起者发起某个事件)。

注意:领域事件是已经发生,并且很重要(需要存储到数据库里)
在这里插入图片描述
疑问:用户选餐是不是一个领域事件呢?
是过去已经发生的事情,重不重要呢?选餐本质是个查询操作,这些查询的操作是不是一定要记录下来呢?在很多系统是不需要记录的。不考虑分析系统,对于业务系统来说,选餐不是领域事件。

下单,接单,就绪,派送,送达需要记录下来,存储到数据库中,因为已经发生,所以命名是过去式。

Ⅱ、用每一个领域事件作为中心,分析和这件领域事件相关的人和事。

在这里插入图片描述
命令:蓝色
和命令有关的人和事情:黄色便签纸标注
触发者:标注小人
箭头:标识有关系的人和事情,比如用户下有地址。识别对象之间是否有聚合关系。
聚合:整体---->部分。例如,用户有很多数据,地址是用户的一些数据,

在这里插入图片描述
在这里插入图片描述

如何识别聚合?
Ⅰ、整体与部分关系
Ⅱ、部分的生命周期在整体范围内,整体产生之前,部分不能产生。整体被删除了,部分也要被删除。

如果菜单是公用的,每个饭店都是引用菜单。一个饭店没有的时候,菜单就有了。
如果每个饭店有各自的菜单,当前饭店没有的时候,这个饭店的菜单也没有,所以就是是聚合。

Ⅲ、识别限界上下文

在我们整个项目里,有很多业务场景,在每次业务场景里,都有各自不同的领域对象,在不同的领域对象之间,会有各自密密麻麻的关系。那么现在是要绘制成一个个密密麻麻的大图,还是按照业务场景绘制出一个个小图呢?

限界上下文:业务场景就把系统划分了很多部分,这些部分就成为了限界上下文。

各个限界上下文又不是相互孤立的,又有相互的联系,相互之间的联系就是上下文地图。
通过限界上下文划分微服务,上下文地图就是各各微服务之间的接口。

在这里插入图片描述在用户下单的时候,需要用户,用户地址。用户信息来自用户注册的上下文中。
在这里插入图片描述

Ⅳ、微服务的拆分

在这里插入图片描述
用户和饭店是支持域,不管在用户下单还是接单,派送的时候,都需要用到用户和饭店的领域的,所以叫支持域名。

注意:DDD指导的是后端微服务。
前端的设计根据原型

Ⅴ、领域事件的通知:

push主动:上游做了事情以后,下游立马响应。比如上游下了单,下游立即接单。
pull被动:挂号与接诊。挂号暴露接口,医生接诊的时候调用挂号的接口。医生什么时候需要接诊的时候,接口查一下,所以下游不需要存一份 。患者挂号以后,不需要立即通知,所以不需要

Ⅵ、对每一个领域事件,进行领域建模,形成领域模型。

用户下单领域模型:
在这里插入图片描述
坏处:每一次查询订单的时候都要调用用户注册的接口。
每次查询菜品明细的时候需要菜单名称

**
所以进行一些调整:把用户和用户地址的一些信息冗余到订单对象里,那么在查询订单的时候,就不需要再去访问用户注册服务,只有在查询更详细的信息的时候,再去远程调用。
(如果用户基本信息那边变了的话怎么办呢)
**
在这里插入图片描述

饭店接单领域模型
因为采用了推的方式,所以,饭店接单这边冗余了一份订单对象
在这里插入图片描述
用户订的取消时间字段,饭店的订单也要有取消时间,因为取消时间对于饭店业务是有用的。
用户订单的取消时间字段,对于骑手主题域的是没有业务意义的,因为在骑士派送微服务是没有操作的。

问题:如果用户接单的订单发生了变更,饭店接单和骑士派送冗余的订单需要修改么
思路:订单在不同的主题域里不用完全保持一致,当上游增加了一些字段的时候,对于下游,要看看这些增加的字段对我自己的业务有没有意义。如果没有意义,就不需要同步的修改,如果说这些字段对我当前主题域来说很重要,要进行业务的调整和业务的修改,那么需要同步的修改,进行同步的操作。
目的:在每一次需求变更的时候,每一次修改的范围尽量缩小。每来一个需求,更改一个微服务,但是这样的情况不一定在所有的微服务都能保证,当我们不能保证只改一个微服务的时候,我们的思路是尽量减少微服务修改的范围。

二、领域对象落地到程序设计:落实到三种对象

1、服务Service:

领域建模中表示某些i行为或者操作。接受用户的请求,执行相应的方法。数据在哪的?在实体和值对象中

2、实体Entity:

领域建模中标识每一个业务个体的领域对象。关注事物的每个个体。

3、值对象Value Object:

领域建模中标识某个客观事物的领域对象。等于字典表。关注事物的类型。
注意:不需要特别区分是是实体还是值对象,统一称之为领域对象,因为不分清楚对开发影响也不大。

4、两种设计

①贫血模型设计

在这里插入图片描述

下单:调用完订单service下单,然后调用订单dao,订单明细dao。并且两个dao在一个service里。并且要管缓存。

思考:订单service满足单一职责么?订单管理dao,又要缓存,业务操作,不是单一职责的。

②充血模型设计:service只负责业务操作,只负责save领域对象,那么怎么save具体交给仓库。

在这里插入图片描述

注意:订单service不能单独操作订单明细只能通过聚合根导航。只能操作整体不能操作部分。

5、聚合Aggregate:把整体和部分的关系,通过整体封装起来,整体就是聚合根。

在这里插入图片描述

6、工厂:负责装配,将订单,订单明细,用户信息装配。

7、仓库:类似dao。同时要维护对象之间的关系。

在这里插入图片描述

三、领域驱动设计的使用范围:

1、适用于:事务的增删改,并且在增删改的时候涉及到的查询。

2、不适用,数据统计类。比如统计所有的订单明细预测趋势。所以就不需要遵循领域驱动了。

3、应对方法:CQRS的引入,也就是查询命令相分离。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值