极客时间已完结课程限时免费阅读

12 | 领域建模:如何用事件风暴构建领域模型?

12 | 领域建模:如何用事件风暴构建领域模型?-极客时间

12 | 领域建模:如何用事件风暴构建领域模型?

讲述:欧创新

时长16:06大小11.04M

你好,我是欧创新。
还记得我在 [第 01 讲] 中说过,微服务设计为什么要选择 DDD 吗?其中有一个非常重要的原因,就是采用 DDD 方法建立的领域模型,可以清晰地划分微服务的逻辑边界和物理边界。可以说,在 DDD 的实践中,好的领域模型直接关乎微服务的设计水平。因此,我认为 DDD 的战略设计是比战术设计更为重要的,也正是这个原因,我们的内容会更侧重于战略设计。
那么我们该采用什么样的方法,才能从错综复杂的业务领域中分析并构建领域模型呢?
它就是我在前面多次提到的事件风暴。事件风暴是一项团队活动,领域专家与项目团队通过头脑风暴的形式,罗列出领域中所有的领域事件,整合之后形成最终的领域事件集合,然后对每一个事件,标注出导致该事件的命令,再为每一个事件标注出命令发起方的角色。命令可以是用户发起,也可以是第三方系统调用或者定时器触发等,最后对事件进行分类,整理出实体、聚合、聚合根以及限界上下文。而事件风暴正是 DDD 战略设计中经常使用的一种方法,它可以快速分析和分解复杂的业务领域,完成领域建模
那到底怎么做事件风暴呢?事件风暴需要提前准备些什么?又如何用事件风暴来构建领域模型呢?今天我们就来重点解决这些问题,深入了解事件风暴的全过程。

事件风暴需要准备些什么?

1. 事件风暴的参与者

事件风暴采用工作坊的方式,将项目团队和领域专家聚集在一起,通过可视化、高互动的方式一步一步将领域模型设计出来。领域专家是事件风暴中必不可少的核心参与者。很多公司可能并没有这个角色,那我们该寻找什么样的人来担当领域专家呢?
领域专家就是对业务或问题域有深刻见解的主题专家,他们非常了解业务和系统是怎么做的,同时也深刻理解为什么要这样设计。如果你的公司里并没有这个角色,那也没关系,你可以从业务人员、需求分析人员、产品经理或者在这个领域有多年经验的开发人员里,按照这个标准去选择合适的人选。
除了领域专家,事件风暴的其他参与者可以是 DDD 专家、架构师、产品经理、项目经理、开发人员和测试人员等项目团队成员。
领域建模是统一团队语言的过程,因此项目团队应尽早地参与到领域建模中,这样才能高效建立起团队的通用语言。到了微服务建设时,领域模型也更容易和系统架构保持一致。

2. 事件风暴要准备的材料

事件风暴参与者会将自己的想法和意见写在即时贴上,并将贴纸贴在墙上的合适位置,我们戏称这个过程是“刷墙”。所以即时贴和水笔是必备材料,另外,你还可以准备一些胶带或者磁扣,以便贴纸随时能更换位置。
值得提醒一下的是,在这个过程中,我们要用不同颜色的贴纸区分领域行为。如下图,我们可以用蓝色表示命令,用绿色表示实体,橙色表示领域事件,黄色表示补充信息等。补充信息主要用来说明注意事项,比如外部依赖等。颜色并不固定,这只是我的习惯,团队内统一才是重点。

3. 事件风暴的场地

什么样的场地适合做事件风暴呢?是不是需要跟组织会议一样,准备会议室、投影,还有椅子?这些都不需要!你只需要一堵足够长的墙和足够大的空间就可以了。墙是用来贴纸的,大空间可以让人四处走动,方便合作。撤掉会议桌和椅子的事件风暴,你会发现参与者们的效率更高。
事件风暴的发明者曾经建议要准备八米长的墙,这样设计就不会受到空间的限制了。当然,这个不是必要条件,看各自的现实条件吧,不要让思维受限就好。

4. 事件风暴分析的关注点

在领域建模的过程中,我们需要重点关注这类业务的语言和行为。比如某些业务动作或行为(事件)是否会触发下一个业务动作,这个动作(事件)的输入和输出是什么?是谁(实体)发出的什么动作(命令),触发了这个动作(事件)…我们可以从这些暗藏的词汇中,分析出领域模型中的事件、命令和实体等领域对象。

如何用事件风暴构建领域模型?

领域建模的过程主要包括产品愿景、业务场景分析、领域建模和微服务拆分与设计这几个重要阶段。下面我以用户中台为例,介绍一下如何用事件风暴构建领域模型。

1. 产品愿景

产品愿景的主要目的是对产品顶层价值的设计,使产品目标用户、核心价值、差异化竞争点等信息达成一致,避免产品偏离方向。
产品愿景的参与角色:领域专家、业务需求方、产品经理、项目经理和开发经理。
在建模之前,项目团队要思考这样两点:
用户中台到底能够做什么?
它的业务范围、目标用户、核心价值和愿景,与其它同类产品的差异和优势在哪里?
这个过程也是明确用户中台建设方向和统一团队思想的过程。参与者要对每一个点(下图最左侧列的内容)发表意见,用水笔写在贴纸上,贴在黄色贴纸的位置。这个过程会让参与者充分发表意见,最后会将发散的意见统一为通用语言,建立如下图的产品愿景墙。如果你的团队的产品愿景和目标已经很清晰了,那这个步骤你可以忽略。

2. 业务场景分析

场景分析是从用户视角出发的,根据业务流程或用户旅程,采用用例和场景分析,探索领域中的典型场景,找出领域事件、实体和命令等领域对象,支撑领域建模。事件风暴参与者要尽可能地遍历所有业务细节,充分发表意见,不要遗漏业务要点。
场景分析的参与角色:领域专家、产品经理、需求分析人员、架构师、项目经理、开发经理和测试经理。
用户中台有这样三个典型的业务场景:
第一个是系统和岗位设置,设置系统中岗位的菜单权限;
第二个是用户权限配置,为用户建立账户和密码,设置用户岗位;
第三个是用户登录系统和权限校验,生成用户登录和操作日志。
我们可以按照业务流程,一步一步搜寻用户业务流程中的关键领域事件,比如岗位已创建,用户已创建等事件。再找出什么行为会引起这些领域事件,这些行为可能是一个或若干个命令组合在一起产生的,比如创建用户时,第一个命令是从公司 HR 系统中获取用户信息,第二个命令是根据 HR 的员工信息在用户中台创建用户,创建完用户后就会产生用户已创建的领域事件。当然这个领域事件可能会触发下一步的操作,比如发布到邮件系统通知用户已创建,但也可能到此就结束了,你需要根据具体情况来分析是否还有下一步的操作。
场景分析时会产生很多的命令和领域事件。我用蓝色来表示命令,用橙色表示领域事件,用黄色表示补充信息,比如用户信息数据来源于 HR 系统的说明。

3. 领域建模

领域建模时,我们会根据场景分析过程中产生的领域对象,比如命令、事件等之间关系,找出产生命令的实体,分析实体之间的依赖关系组成聚合,为聚合划定限界上下文,建立领域模型以及模型之间的依赖。领域模型利用限界上下文向上可以指导微服务设计,通过聚合向下可以指导聚合根、实体和值对象的设计。
领域建模的参与角色:领域专家、产品经理、需求分析人员、架构师、项目经理、开发经理和测试经理。
具体可以分为这样三步。
第一步:从命令和事件中提取产生这些行为的实体。用绿色贴纸表示实体。通过分析用户中台的命令和事件等行为数据,提取了产生这些行为的用户、账户、认证票据、系统、菜单、岗位和用户日志七个实体。
第二步:根据聚合根的管理性质从七个实体中找出聚合根,比如,用户管理用户相关实体以及值对象,系统可以管理与系统相关的菜单等实体等,可以找出用户和系统等聚合根。然后根据业务依赖和业务内聚原则,将聚合根以及它关联的实体和值对象组合为聚合,比如系统和菜单实体可以组合为“系统功能”聚合。按照上述方法,用户中台就有了系统功能、岗位、用户信息、用户日志、账户和认证票据六个聚合。
第三步:划定限界上下文,根据上下文语义将聚合归类。根据用户域的上下文语境,用户基本信息和用户日志信息这两个聚合共同构成用户信息域,分别管理用户基本信息、用户登录和操作日志。认证票据和账户这两个聚合共同构成认证域,分别实现不同方式的登录和认证。系统功能和岗位这两个聚合共同构成权限域,分别实现系统和菜单管理以及系统的岗位配置。根据业务边界,我们可以将用户中台划分为三个限界上下文:用户信息、认证和权限。
到这里我们就完成了用户中台领域模型的构建了。那由于领域建模的过程中产生的领域对象实在太多了,我们可以借助表格来记录。

4. 微服务拆分与设计

我们在基础篇讲过,原则上一个领域模型就可以设计为一个微服务,但由于领域建模时只考虑了业务因素,没有考虑微服务落地时的技术、团队以及运行环境等非业务因素,因此在微服务拆分与设计时,我们不能简单地将领域模型作为拆分微服务的唯一标准,它只能作为微服务拆分的一个重要依据。
微服务的设计还需要考虑服务的粒度、分层、边界划分、依赖关系和集成关系。除了考虑业务职责单一外,我们还需要考虑将敏态与稳态业务的分离、非功能性需求(如弹性伸缩要求、安全性等要求)、团队组织和沟通效率、软件包大小以及技术异构等非业务因素。
微服务设计建议参与的角色:领域专家、产品经理、需求分析人员、架构师、项目经理、开发经理和测试经理。
用户中台微服务设计如果不考虑非业务因素,我们完全可以按照领域模型与微服务一对一的关系来设计,将用户中台设计为:用户、认证和权限三个微服务。但如果用户日志数据量巨大,大到需要采用大数据技术来实现,这时用户信息聚合与用户日志聚合就会有技术异构。虽然在领域建模时,我们将他们放在一个了领域模型内,但如果考虑技术异构,这两个聚合就不适合放到同一个微服务里了。我们可以以聚合作为拆分单位,将用户基本信息管理和用户日志管理拆分为两个技术异构的微服务,分别用不同的技术来实现它们。

总结

今天我们讲了事件风暴的设计方法以及如何用事件风暴来构建领域模型。事件风暴是一种不同于传统需求分析和系统设计的方法,最好的学习方法就是找几个业务场景多做几次。
综合我的经验,一般来说一个中型规模的项目,领域建模的时间大概在两周左右,这与我们传统的需求分析和系统设计的时间基本差不多。但是如果在领域建模的过程中,团队成员全员参与,在项目开发之前就建立了共同语言,这对于后续的微服务设计与开发是很有帮助的,时间成本也可以视情况降低。
其实我也了解到了,很多开发人员在初次学习 DDD 时,似乎并不太关心领域建模,而只是想学学 DDD 的战术设计思想,快速上手,开发微服务。我想这是对 DDD 的一个误解,这已经偏离了 DDD 的核心设计思想,即先有边界清晰的领域模型,才能设计出清晰的微服务边界,这两个阶段一前一后是刚需,我们不能忽略。

思考题

请找一个你擅长的业务领域,试着用事件风暴来构建一下领域模型。
欢迎留言分享,期待你的打卡!
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 25

提建议

上一篇
11 | DDD实践:如何用DDD重构中台业务模型?
下一篇
13 | 代码模型(上):如何使用DDD设计微服务代码模型?
 写留言

精选留言(78)

  • 醇梨子
    2019-12-31
    我觉得 像这种东西,你理论写的再多,也没什么实践意义,人类天生具备的能力就是模仿,市面上培训DDD的东西那么多,公司那么多,为什么最后还是做不了DDD? 像这种东西,你何不从头就引入 一个业务场景,哪怕不大的,从前到后 拆解出来,比你写这种理论 写一万篇都有用,我说实话,我所有都看完了,除了一些概念,我真的学会领域建模了?
    共 22 条评论
    164
  • Dwan
    2019-11-11
    DDD: 事件风暴--产品愿景--场景分析--领域建模--微服务拆分与设计。 传统: 产品需求--需求分析--详细设计--ER模型--UML设计 貌似最后都能产生模型图,一个叫领域模型,一个叫ER图,是不是关键就在这里,一个是面向业务领域建模,一个是面向底层数据层设计,也是DDD和传统的分水岭?

    作者回复: 是这个意思。DDD领域建模优先,领域建模的时基本不考虑数据模型和数据库实现。在微服务具体落地的时候才考虑数据实体的设计。

    共 5 条评论
    45
  • 伊来温
    2020-06-29
    有个问题请教下,商品的收藏功能,应该被划分在用户上下文呢还是商品上下文。感觉语意上两边都是通的

    作者回复: 根据单一职责的设计原则,用户上下文应该只负责用户相关的管理职能。商品的收藏虽然跟用户关联,但应该属于商品上下文,商品上下文内可能会有商品目录聚合和商品收藏聚合等。在设计时,你可以将收藏的商品与用户ID建立关联就可以了,用户ID是值对象。用户登录时,可以根据用户ID查询到匹配的商品收藏清单。

    共 4 条评论
    15
  • suke
    2020-06-27
    做微服务拆分为什么还要叫上产品、测试,和项目经理,他们的发言有用么 我就想问

    作者回复: 领域建模的过程不光是建立一个领域模型,更关键的是建立团队通用语言的过程。所以需要团队成员尽早参与,后面开发和测试就会容易很多,也不会出现方向偏离。

    共 4 条评论
    9
  • Harris
    2020-01-05
    个人理解领域建模的核心是识别出领域模型并做到“高内聚,低耦合”;最后一步微服务拆分与设计并不一定是一定要微服务,可以是一个模块、一个包等等。

    作者回复: 是这样的,其实DDD刚出来的时候并不是为微服务设计的。你可以根据自己得需要,做好领域建模和划分好边界,刚开始并不一定要拆的很细,等真正需要拆分的时候再拆,用DDD设计的系统很容易解耦,很容易拆分出微服务来的。

    9
  • 张迪
    2019-11-14
    看着这个划分的领域,完全不知道怎么落地。

    作者回复: 有什么疑问,咱们可以谈讨哈。

    共 4 条评论
    8
  • myking
    2020-10-07
    老师能不能用把ddd带入到rbac的实战设计里面去?我感觉这个和订单比起来设计到的聚合根的选择更复杂的多,比如是不是应该有userRole的聚合根、roleMenu的聚合根。事件有删除menu删除role等等。在这种情况下应该如何处理呢

    作者回复: 这个需要根据您的业务场景来具体分析。我试着来分析一下。一般来说在用户权限体系里,会有User、Role等聚合,其中Role作为聚合根,会引用Menu实体,建立role的菜单权限体系。User和Role聚合主要用于管理用户以及角色等基础信息,比如用户的增删改查,删除Role中的菜单权限,删除Role等基本操作。 在进行用户权限配置时会有另外一个聚合UserRole,这个聚合的聚合根引用用户值对象和Role值对象,在这个聚合管理用户的角色权限配置,建立User和Role之间的关联。

    共 5 条评论
    7
  • Tan
    2019-12-23
    欧老师好,请教个问题: 信贷风控系统,客户提交申请信息,根据客户信息查几十个第三方信息(征信报告、欺诈分、企查查...)来获取客户相关信息然后放到规则引擎跑规则,最后算出客户授信金额。感觉这个系统一时半会没发下手划分领域和子域,麻烦老师指点一下,谢谢!

    作者回复: 你说的这个场景不是富领域模型,可能找不出聚合根,因此不适合用聚合的方式来做。但是你可以用DDD的分层架构来划分不同的服务,按照外层依赖内层服务的调用关系来开发。

    共 3 条评论
    5
  • marker
    2019-11-13
    老师,能给我们说说四色建模或彩色建模?

    作者回复: 这一块研究的还不太深入呢。后面我再研究一下。

    5
  • 睁眼看世界
    2019-11-12
    老师,学习到这里还是云里雾里,感觉学了一大堆概念,有个DDD这个理念。公司一般都是需求驱动,很少会花费大量精力去领域建模。老师,请问你们具体是如何推动DDD落地的?

    作者回复: 领域建模的目的是为了微服务的设计,领域模型是开始,DDD是一种不同于传统设计的方法 ,先有领域模型,然后才有微服务设计,这样设计的微服务边界很清晰,而不是靠拍脑袋设计微服务。等学完后面全部DDD的内容后,你就知道其中的奥秘了。

    共 3 条评论
    4
  • Geek_75d94a
    2020-07-09
    学完感觉还是一脸懵逼,很多时候不知道哪些事件应该挂在哪个实体下面。像是一个团队里面,存在队长和队员,只有队长可以解散团队。那么解散团队这个操作,是放在团队实体上,还是队长实体上?

    作者回复: 事件是独立的,一些操作发生后会产生事件,事件主要用于上下游业务的数据流转和领域模型和微服务解耦,不用挂到某个实体下面。团队的管理在聚合根,聚合根的有些职能会拿出来放到工厂和仓储里面,比如聚合实体的初始化,聚合数据的持久化。解散团队的操作当然在聚合根实体。

    2
  • learn more
    2022-05-04
    构建领域模型的过程和敏捷开发的故事拆分非常接近,尤其使用了看板、便利贴以后,简直就是同一套方法论,不同的语言表达而已。
    1
  • 徐李
    2021-12-16
    事件风暴,就是把团队的人都召集起来,大家头脑风暴,各抒己见,然后汇总得出领域模型,限界上下文,实体,值对象,命令等。
    1
  • jiankang
    2021-08-31
    我觉得不少同学还是本着技术思维学习,具体讲是用确定的技术手段去解决确定的业务需求。 而DDD是一种思想,或者说是一种解决问题的方法论, 在这种方法论的指导下,大概率不会跑偏。
    1
  • 李二木
    2020-11-26
    DDD 适合敏捷开发吗?项目初期需求不是那么明确。都是在迭代中完善的。

    作者回复: 有没有觉得事件风暴的过程有点像敏捷开发的模式所提倡的方式。DDD的开发和设计非常适合敏捷开发,而且用DDD拆分出的微服务就可以很好的适合2-pizza团队的敏捷开发模式。

    1
  • suke
    2020-06-27
    怪不得ddd不好落地,且不说学习ddd付出的成本。一个领域建模要2周?还要叫上这么多人开会讨论 产出结果 可想效率之低

    作者回复: 两周的时间基本上领域模型和微服务的所有设计就作完了,剩下的事情只是功能级的开发。通过一起领域建模,大家基本都了解到了所有的设计过程和实现细节,建立了统一语言,磨刀不误砍柴工,后面开发的工作就很容易了,所以效率并不会比传统的开发方式低。

    共 3 条评论
    1
  • 小谢同学
    2020-02-17
    有几个问题想请教下老师: 1. 中台类的项目通常是否也需要不断的迭代优化? 2. 假设要做一个2b的中台项目,集合ddd与敏捷开发,是否可以先根据用户旅程来遍历业务细节找出所有领域对象,最终按照ddd战略设计完成mvp产品的领域建模和限界上下文划分,这时候引入用户故事根据每一个边界内的聚合进行发布计划与迭代开发? 3. ddd与敏捷的融合,我认为有很多实践可以复用,例如白板、站会、用户旅程、工作坊,而到了战术设计阶段完全可以借用极限编程与精益的思想,比如引入结对编程,避免浪费等等,这样理解是否正确?谢谢
    展开

    作者回复: 领域模型不会一成不变的,所以项目也会不断迭代。 敏捷和DDD结合会是未来的趋势,理解后你可以将它们灵活组合来用。

    1
  • 西野
    2019-11-28
    老师请教一下,领域服务和应用服务的区别是什么??

    作者回复: 建议你看一下第7节。DDD分层架构:有效降低层与层之间的依赖。里面有详细介绍。

    1
  • miniluo
    2019-11-12
    ddd从我做起
    1
  • 北天魔狼
    2019-11-12
    感觉最近要做的聚合交易项目就可以小试一下,老师已经列过类和方法名称,对照上下文和聚合可以照着葫芦画瓢了。现行项目不准备也没必要微服务,但是可以写好代码

    作者回复: 走两次就大概知道怎么去做了。理解了理念以后,就不必受一些条条框框的限制了,路是自己慢慢趟出来的,选择最适合自己的方式。

    共 4 条评论
    1