DDD聚合的数学模型 -Thomas Ploch


软件不是孤立的工件。它必须嵌入到使用和生产它的人们的社会技术环境中,并与环境不断相互作用。我们需要知道的是,复杂的系统如何显示我们作为系统设计者试图捕获有用的抽象的行为。

“组织是动态的,层次结构化的实体。这种活力体现在每个组织级别的重大事件的出现。”
Morgeson F.,Mitchell T.和Liu D.2015。事件系统理论:面向事件的原始科学方法 ]

我们将这些事件称为事件处理events processes模式。系统通过事件处理才能实现目标,例如在线销售书籍或向餐厅提供座位预订。一个称为处理理论(process theories)的大型研究主题正在试图了解事件的模式如何导致积极的结果。归根结底,它们是“关于发生了什么事以及谁在什么时候做了什么的事情(事件),事件、活动和选择随时间变化”(Langley,A。1999。根据过程数据进行理论化的策略)。

协作时间建模的兴起
在过去的几年中,出现了捕获这些事件处理的新方法。事件风暴,故事映射或领域故事讲述都是这些方法的示例,这些方法可以认识到了解事件的重复模式,能在设计可行的解决方案中发挥很大的作用。与传统的静态建模技术相比,这些方法通常与组织现实的重叠更大。
时间建模还影响了经验丰富的DDD从业人员在使用聚合Aggregates时所做的战术设计选择。将聚合定义为命令(来自环境的刺激),行为(对可以改变系统响应机制的传入刺激的反应)和事件(响应系统状态变化的系统信号)的组合。例如,“事件溯源”模式就是建立在这些基本设计选择的基础上,使事件的按时间顺序排列(即“时间”)模式成为其设计的核心要素。

如果我们可以通过按时间顺序排列的一系列事件定义一些聚合,那么这些聚合也是处理process。

重新发现有限状态机
建模过程在计算中并不是什么新鲜事物。而自动机理论似乎特别有趣:
有限状态机(FSM)公式用于描述根据一组规则信息或任务从一种状态移动到另一种状态以采取行动的过程。状态包含最少的信息,这些信息与输入的知识一起可以确定输出。

术语“ 自动机”和“ 机器”可互换使用,因此,当我们谈论FSA时,也指FSM。
转换为我们的处理process术语后,FSM会处理系统激励流(命令),强制执行不变式并更改系统状态(行为)。

一个FSM Α是一个5元组:
A =⟨S,C,δ:S x C→S,S₀,F:F⊂S⟩

  • S是一个非空的有限状态集
  • C是命令语言,一种非空的有限命令集
  • δ是行为的集合—状态和命令与状态的关系
  • S₀是初始状态
  • F是最终状态的非空有限集,其中F是S的子集

有了这个定义,我们将需要从领域专家的知识中得出命令和状态字母,然后通过行为功能将点连接起来。

宇宙是一个混乱的地方
我们乐于寻找确定性的解决方案,以解决复杂的问题,而这种方式本质上不是确定性的。作为一种建模方法,DDD包含了系统的意外行为-这是我认为将DDD思维应用于复杂问题几乎总是一个好选择的主要原因之一。这意味着根据当前情况,对系统刺激的反应通常会有所不同。想象自己是一个呼叫中心代理,突然被建议将针对特定主题的呼叫重新路由给主管。世界只是不可预测的。

非确定性有限原子自动机(NDFA)
为了解决这个混乱的世界,自动机理论提供了两种可以表达这些差异的FSA类型-非确定性(NDFA)和确定性(DFA)FSA。
DFA和NDFA之间的差异很小。DFA对于每个状态和命令对仅具有一个转换,而NDFA可以具有多个转换,甚至没有。从数学上讲,它们都是等效的。您始终可以将DFA转换为NDFA,然后再次返回。
但是,在表示它们所需的复杂程度之间确实存在差异。具有n个状态的NDFA 可以转换为具有2个状态的DFA 。对于10个状态的相当复杂的NDFA,我们在DFA中最多需要1024个状态来表示它!
使用NDFA时,您为了简化而牺牲了确定性!

事件在哪里?
如果我们重新收集FSA的定义(由命令和状态语言与“行为”配对定义),则可能会认识到当前尚无办法将任何信号发回系统。那么,事件在哪里?
普通的NDFA似乎不足以代表我们的处理process。自动机理论是否可以提供在这种情况下可以使用的另一个概念?
剧透:是的,可以!

引入有限状态传输器(FST)
让我们看一下有限状态传感器的正式定义。这是一个六元组:
⟨=⟨S,C,E,δ:S x C→S,S₀:S₀S,ω:S x C→E→

  • S是一个非空的有限状态集
  • C是命令语言,一种非空的有限命令集
  • E是事件语言,非空的有限事件集
  • δ是行为的集合,即状态和命令对与形式为δ的状态的关系:S x C→S
  • S₀是初始状态的非空有限集,其中S₀⊂S(S₀是S的子集)
  • ω是状态和命令对与形式为ω的事件的输出关系:S x C→E

现在我们有了命令,行为和事件,我们可以将process建模为非确定性FST。让我们开始行动并在示例场景中使用数学!

示例:设计用户注册过程
假设我们有一个很棒的Event Storming会议,现在正尝试将数学应用于特定问题的紧缩知识-用户注册过程。我们必须定义命令,状态和事件等名词,而行为和事件是响应特定的行为而输出的。

1. 我们从构建事件语言开始。

  • 发送确认邮件开始注册后,我们要确保客户确实可以访问提供的电子邮件地址,因此我们通过带有确认链接的电子邮件发送确认邮件。
  • 确认重发当确认已过期,我们想使我们的客户能够轻松地重新发送确认,也许以前的邮件被垃圾邮件过滤器捕获。
  • 帐户已确认当客户完成确认后,我们说该帐户现已确认。
  • 帐户是通过GDPR请求删除的。根据欧洲法律,我们有义务删除所有个人数据。

它遵循:
Ε = {ConfirmationSent,ConfirmationResent,AccountConfirmed,AccountDeleted}

2.类似于事件的命令:

  • 开始注册
  • 确认帐号
  • 重发确认
  • 满足GDPR要求

它遵循:
C = {StartRegistration,ConfirmAccount,ResendConfirmation,FulfillGDPRRequest}

3. 设计状态
在设计状态时,我们应该牢记一个原则:
状态包含最少的信息,这些信息与输入的知识一起可以确定输出。

我们的目标是找到所需的最少信息量,以进行适当的反应。在这里,少就是多。
该示例不着重于管理数据,但是可以定义状态的属性-这不会影响通用公式。

  • 潜在客户这是我们的初始状态。任何未注册的客户都是潜在的!
  • 需要确认
  • 已确认
  • 已删除

S = {PotentialCustomer,RequiresConfirmation,Confirmed,Deleted}

S₀ = { PotentialCustomer }

4. 反应
我们需要做的最后一件事是定义行为(δ)和事件(ω)函数。

δ : S x C → S = {
(PotentialCustomer, StartRegistration) → RequiresConfirmation,
(RequiresConfirmation, ResendConfirmation) → RequiresConfirmation,
(RequiresConfirmation, ConfirmAccount) → Confirmed,
(Confirmed, FulfillGDPRRequest) → Deleted,
(RequiresConfirmation, FulfillGDPRRequest) → Deleted
}

和:
ω : S x C → E = {
(PotentialCustomer, StartRegistration) → ConfirmationSent,
(RequiresConfirmation, ResendConfirmation) → ConfirmationResent,
(RequiresConfirmation, ConfirmAccount) → AccountConfirmed,
(Confirmed, FulfillGDPRRequest) → AccountDeleted,
(RequiresConfirmation, FulfillGDPRRequest) → ϵ
}

完工
现在,我们终于可以将我们的用户注册汇总(或更确切地说是不确定的有限状态转换器)构造为:

Τ=⟨S,C,E,δ,S₀,ω⟩

并向其发送以下命令:

I = {
StartRegistration,
ResendConfirmation,
ConfirmAccount,
FulfillGDPRRequest
}

作为回应,我们将收到以下事件:

E = {
ConfirmationSent,
ConfirmationResent,
AccountConfirmed,
AccountDeleted
}

结论

  • 我们已经了解到,面向process的时间模型在处理复杂系统的行为时非常匹配-以及协作建模技术如何塑造了我们对这些系统的理解。
  • 我们回顾了计算技术的过去,以重新发现自动机理论作为对流程进行建模的一种手段,探索了不同类型的机器(FSA,DFA,NDFA,FST),并将它们映射到时间聚合设计的所需属性。
  • 我们将数学付诸实践,并设计了一个“用户注册汇总”作为具体示例。

点击标题见原文原图。