Alberto Brandolini
统一语言的素材,包含对商业流程的共同理解,包含名词使用、责任范围、使用者体验等。
—份整体流程的概览图(Big Picture)
可以找出商业流程中的核心价值、风险与机会。
导入DDD的好起点
事件风暴方法减少了创建全面的业务域模型所需的时间。过去需要数周的时间,一次研讨会可以在几个小时内完成。
事件风暴不使用复杂的UML,而是将过程分解为技术和非技术利益相关者都可以理解的简单术语。不需要有过多准备,直接识别利益相关者就可以开始。
事件风暴的目标之一是使建模变得有趣。这是一种动手的领域建模方法,可邀请每个人参与和交互。除了使参与者更加愉快之外,事件参与者还可以使参与者获得更多有价值的见解,因为参与者可以更轻松地参与该过程并提供他们的建议和专业知识。
事件风暴不是数据建模,但通过大家讨论可以快速实施和验证的行为模型。同时为了获得最佳结果,团队应将事件风暴与面向领域驱动设计的实施相结合。
Big Picture(概览图)
理清混沌商业系统,凸显出合作关系、边界、责任归属与不同利益相关者的观点。邀请任何有兴趣的人、不用限制讨论范围。
找出瓶颈、核心价值甚至是新的解决方案
主要以Event.、 System、Question为主。
适合新创或小团队(人少、技术债少)
Process Modelling(流程模型)
讨论特定功能流程,以确保大家理解没有明显分歧,最后达到理解的一致性。
有明确范围,所以路径越完整越好。
在细节中找出流程的Bug,并且每个Bug都需要被处理。
包含Event、Actor、Command、 System、Policy、 Read Modelo
Software Design(软件开发)
利用前面的产出进一步设计软件
加入Aggregate(聚合)、 BoundedContext(限界上下文)建立模型边界。
用词更加精准
提前准备:人事时地物
传统的建模过程通常需要一名或几名研发人员来一起进行类设计、接口设计,通讯协议和数据映射等。而事件风暴则可能是较大的不同团队的成员来一起构建领域模型。
谁是合适的人?根据Brandolini的说法,他们是知道提出正确问题和拥有答案的人。该小组可能是代表用户体验,业务,架构,开发,运维和营销等利益相关者的混合体。
主持人/Facilitator:
建议一定要有一名参与者负责主持会议进行、推动议程讨论。要严格注意时间与流程。最好不要跟Domain Expert重复。
领域专家(们)Domain expert(s):
专案的主要推动者,或是拥有足够领域知识的人,建议最好有一定的决定权,在陷入泥沼时才可以做出决定。如果是新创领域,可以事先做好使用者访谈或是找使用者来参加。可以不只一名。
其他利益相关者Other Stackholder:
可能是参与专案的工程师、设计师,也可能任何能提供专业意见的人士如业务、商业分析师甚至是主管。
•橘色(正方形 76*76):Event 事件
•蓝色(正方形):Command 命令
•紫色(长方形): Policy/Process 商业政策/流程
•黄色(小张长方形):Actor 角色
•黄色(长方形):Aggregate 聚合
•粉红色(长方形):System 外部系统
•红色(正方形):Hotspot 热点
•红色(小张长方形):Problem 疑问
•绿色(小张长方形):Opportunity 机会
•绿色(正方形):Read Model 资料读取模型
•白色(大张正方形):Uset Interface 使用者介面
从事件开始
主持人会先请领域专家简介专案需求,然后由领域专家(或是主持人)在画面正中央贴上第一张Event。贴在中间一方面可以灵活拓展,另一方面也能让所有人一起参与。
1.橘色便利贴。
2.使用过去式(根据Alberto Brandolini本人的叙述,使用过去式代表着系统的状态)如订单已成立、货物已送出、早餐已买到等等。
3.领域专家所在乎的事件。
如整合第三方物流时,领域专家可能只在乎送达时间而不在乎中间细节的运输过程。
4.有时间性,请从左到右排列。同时加上时间概念。
如「凌晨三点帐款已对帐完成」、「午夜十二点马车已变成南瓜」,甚至是某个时间点,如「本季度已结束」
「已过了一个月」。
5.可以加上原因。
如「因为密码输入错误三次,所以帐号已被锁住」。
比如商城的订单模块 用户下单事件
状态 主流程
待支付 待审核 待发货 。。。。
提出问题:
比如(主持人此时重要功能是将大家讨论全部针对事情上来)主持人鼓励随时打断、不要放过任何模棱两可,比如:
热点问题(HotSpot)
如果过程中某个节点卡住太久,很有可能是因为领域专家也不太了解这个问题,也有可能是目前资料量不足以做出决定。先贴上一张45度角旋转后的红色的Hotspot待日后解决。
Command
·事件的触发器
·蓝色便签条。
·事件是对过去已发生的陈述,命令表达了对将来发生某些事情的意图。·命令可以是执行也可以是拒绝执行。
例如,如果在订单系统中,库存不足,触发拒绝订单事件
Command的主体可以是用户(Actor)、后台管理也可以是系统触发。
Read Model
一些读取的信息
System
一般由Command或者由第三方回调(支付完成)所触发。System在上一流程完成后,再产生新的Event。
比如用户支付完成,系统生成「卖家发货」、「物接揽收」、「开始分拣」、「运输中」、「商品已到指定取货点」等。
Policy
系统对于特定Event如何回应,Policy就像Event Storming 的侦探一样,可以找出许多尚未发掘的问题或是现有流程矛盾之处。
围绕Aggregate对事件和命令进行分组。
每个Aggregate代表一个特定的业务概念,该概念具有具体的业务功能。
同时在时间表上标记了这些组。刚标好的组,标记聚合可能把时间顺序打乱。
Aggregate想成是一个State Machine(有限状态机),一个Model会有很多的状态,因此一种Aggregate可能会对应到多组Command与Event。
最终聚合定义的模型再结合DDD
如何设计一个电商项目
DDD可以将业务分析与技术进行分离。
我们在进行领域驱动设计时,需要考虑战略设计以及战术设计。包括架构选型。
我们就以我们的一体化商城平台项目为例,我们的一体化商城项目是一套集物流,仓储,电商为一体的智慧电商平台。同时,服务于广大的中小型商家。商家可以在平台进行申请开店。平台提供对应的第三方物流,仓储以及一系列交易保证功能。
一体化商城系统
支撑子域
得到多个聚合 APP下单
用例模型 领域模型 建模
DDD的方法论的核心将我们的问题不断的分解,将大问题分解成为小问题,将大的业务范围分解成小的领域,简单的说就是分而治之,各个击破。
分而治之,我们可能直接会面对大业务,我们无从下手。我们就需要分解,雏形:多少业务功能-每个功能–接口
分解成为高内聚的小领域,可以让我们的业务有边界。但是领域是实际的边界。这就是领域驱动设计的核心。
各个击破,是指的我们的问题被划分成为小领域之后,因为小领域业务内聚,所以说子域的相关度高,同时我们在设计的时候可以对他进行详细设计。并且我们在管理的维度我们也可以对项目进行分工。所以我们的DDD的战略设计是不能替代详细设计的,DDD的本质是为了更加清晰的进行详细设计。
现在微服务是特别流行的,当我们的业务逻辑越发复杂的时候,实际上也可以靠我们的DDD来解决我们的业务逻辑复杂的问题。
首先,我们需要明确一点,我们去使用DDD是干什么事,就是将我们的业务划分为边界清晰的模块。DDD只是其中的方法之一,DDD在这里是方法,不是目标。比如你的业务模型很简单,很容易分析的项目就不需要DDD,短平快,你也不需要。
由于项目过于庞大,导致我们整个项目可以无限极的划分,比如我划分了领域,子域,子子域,限界上下文的划分,本质上不就是子域。
我认为大家不必纠结,这取决于你当前功能的重要性,如果你当前的功能是核心模块,那么这个时候你的划分需要尽可能详细一些,其他的一些子域,划分可以不用那么详细。你认为的局部,在别人看来是整体。高内聚,将与核心业务高度关联的功能,优先收敛。
关于微服务的粒度划分至今是没有粗细的详细标准的。根据业务需要,开发资源,技术实力综合考虑。拆分微服务过细会导致开发难度增加,部署难度增大,维护难度增加,但是迭代成本减少。
建议大家核心领域单独划分模块,非核心可以选择性聚合
领域对象与数据对象,区别:值对象的存储方式
足球运动员指标
抽象的核心是找相同的,对不同事物的相同的地方提取公因式,变相的体现了灵活性。
梳理的视角是什么?
如果对于业务不熟悉,那么我们应该怎么做?
1.时标对象:1.事实的不可变性 2.责任的可追溯性
2.参与方,地,物
3.角色对象
4.描述对象
当业务系统发生了一件事情,这个事情会影响到其他子域的后续动作,那么这个时候我们将这个事情称之为领域事件。
事件订阅的交互,需要注意一个问题,在软件当中,事件模式只能用到最终一致性,需要放弃强一致性,所以,领域事件的产生会引入技术复杂度的权衡。
参见架构代码结构对照表
领域已经确定了,根据领域划分任务,用例图,活动图,时序图,数据库设计,接口设计规范。