使用设计画布发现和建模有界上下文 - Nick Tune

19-07-23 banq
                   

我们如何将大型系统分解为更小,更易于管理的模块化组件?在领域驱动设计中,大型系统被分解为有界上下文,这些上下文在代码中成为微服务和组织中的团队的自然边界。

识别良好边界没有捷径可走。对业务和领域的广泛而深入的了解至关重要。本文介绍的方法围绕这些需求而设计,并使用两个工具来找到最有效的系统设计:EventStorming和Bounded Context Design Canvas。

这种方法的工作方式由以下活动组成:

  • Big Picture EventStorming(最短1小时)
  • 候选的上下文建模(最少30分钟)
  • Domain Flow故事(最少30分钟)
  • 有界上下文设计画布(最少90分钟)
  • 精炼上下文探索(最少45分钟)

我建议为本次研讨会至少分配一整天时间。这将帮助您了解实际需要多长时间才能正确完成。如果你只有一次机会让所有人聚在一起,试着分配两天。

理想情况下,与会者将是领域专家和技术专家的混合体。如果这很难实现,至少尝试让您的领域专家在第一个小时内参与。

建模基础知识回顾

这个研讨会需要很大的空间。如果你能得到的只是一个狭窄的会议室,你会对结果感到失望。每组四人需要至少四米的墙面空间。

请记住:

我们不断在问题空间和解决方案空间之间切换。我们寻找信息,创建模型,寻找更多信息,改进模型等。

研讨会的目标是制定选项并为未来培养或提供更好选择的能力。

1. EventStorming

如果您想设计系统,您需要两件事:对整个系统的足够概述以及每个区域的足够深入的细节。为此,我们从EventStorming开始。

EventStorming是一种协作建模技术,用于从端到端对大型问题域进行建模,同时还能够根据需要深入了解详细信息。如果这是您的第一次,我建议在1-2小时内进行EventStorming。完成EventStorming后,我建议您将小组分成最多4人的小组。

2.候选的上下文发现

通过将您的域作为EventStorm进行广泛和深入的建模,您可以开始将这些片段分组并组织成有界的上下文。可以使用各种技术来开始识别有界上下文。我首选的入门技巧是:

  • 从价值开始 - 确定对业务具有最高价值的域的核心部分。
  • 从简单开始 - 通过将时间线分解为连续步骤来创建简单但天真的模型。(banq注:可依据UML序列图来合并同类项)
  • 寻找关键事件 - 寻找关键业务事件,指出业务流程不同部分之间的状态变化。

最初花费不超过30分钟完成此任务。鼓励该小组创建有界上下文的初始模型作为起点。它不需要是完美的,它不可能是最终的解决方案。

输出应该只是一个有界的上下文名称列表,如在墙上贴后或写在纸上。

从这里开始迭代

您可以立即确定多种可能的方法来建模系统。现在,选择一个可以使用并记下其他可能的模型(稍后会有用)。您可能还意识到您缺少域信息。如果是这样,请考虑进行另一轮EventStorming。

3. Domain Flow Storytelling领域流故事

如何测试我们上述设计的有效性?如何获得改进上述设计的反馈?将这些有界上下文串联起来看看是否可以协作解决整个业务用例。例如,如果领域流程很复杂,具有许多依赖关系和双向关系,则会警告您的设计很脆弱,需要进一步分析。

您可以使用各种可视化技术来建模流程和用例,包括UML序列图和UML用例图。我更喜欢使用领域故事的变体:Domain Flow Storytelling。

通过Domain Flow Storytelling,有界的上下文本身就是故事中的演员。因此,故事始于用户尝试实现一个个功能,然后是有界上下文之间的交互,这样为用户能提供最终的完整解决方案。

对战略Domain Flow建模可以为您提供有界上下文的反馈。它显示了如何协作并相互依赖来执行完整的业务用例。这将指导您探索其他设计机会。

您可以问自己的一个问题是:每个有界上下文的描述是否与它在Domain Flow中扮演的角色一致?如果不是,则可能需要重新设计命名或边界。

从这里迭代

当从Domain Flow识别有界上下文之间的关系时,您可能会立即发现明显的设计缺陷或缺少功能。您可以自由返回上一个活动并更新筛选上下文或执行第二次EventStorming迭代。

在开始重新设计之前,您还可以记下您的设计反馈并从后续活动中收集更多信息。

4.有界上下文设计画布

设计过程的下一步是通过详细说明关键设计标准来设计候选的有界上下文。在您的团队中,选择您认为最重要的有界上下文。将此活动限制为最多3分钟。100%准确并不重要。

现在,绘制一个有界上下文设计画布,并通过以下步骤填写详细信息。我建议使用1张活动挂图或类似尺寸的纸张。

完成以下步骤后,重复此过程,直到定义了所有有界上下文。尝试在您确定的候选有界上下文数量之间平均分配时间。

1. 上下文概述定义

首先填写有界上下文的名称和描述。描述应描述上下文在域中的作用及其在业务中的作用,而不是实现细节。

接下来,确定战略或策略分类。有界上下文是系统的核心部分,支持部分,通用部分还是其他什么?如果您需要帮助选择,请阅读Vladik的帖子

当您无法想出清晰的名称或撰写有凝聚力的精确描述或您的UL术语含糊不清时,请将其视为设计反馈。考虑现在重新设计边界,或者做一个注释并稍后返回(通常更好以后再返回)。

2. 业务规则的提炼和无所不在的统一语言捕获

查找最重要的业务规则或策略 - 尝试选择前3并将其添加到画布。

这也是寻找关键业务词汇或短语的好时机,将它们添加到画布中的统一语言部分。这在整个研讨会期间会不断继续添加单词和短语,这只是一个起点。

3. 强调有界上下文提供的功能是下一个优先事项。这不仅澄清了有界上下文的作用,还提供了丰富的设计反馈。您可以开始提出以下问题:

  • 这种上下文有太多职责责任吗?
  • 这些能力是否具有凝聚力?
  • 这些功能是否在逻辑上与名称和描述保持一致?
  • 如果我们将此功能移到上下文之外会怎么样?

通过设想公共接口开始识别功能。客户可以询问这个有界的上下文以及它们可以调用哪些命令?在此处使用您的领域流的故事,以了解客户在此上下文中需要的是什么。

并非所有功能都是外部激活的命令和查询。一些功能可以在内部触发,例如计划任务,所以也要考虑这些。

有时您会注意到功能集群,如命令,查询和通知。如果是这样,请在画布上将它们聚集在一起,并为群集命名。

从这里迭代

如果您正在努力识别许多功能,或者您觉得有些功能缺失,我建议您返回到您的EventStorm并更详细地模拟这个有界的上下文,并具有特定的外部焦点,以寻找其他上下文/服务所需的功能。

3.1 能力分层

将画布上的每个功能分解为子功能。这种额外的粒度为您提供了更多的功能,增加了寻找替代模型的能力。

画布上通常没有空间。所以找另一张纸或墙壁空间。您可以在感觉有益的情况下深入多层。

4. 依赖性

如果我们想要模块化,依赖性是必不可少的,但依赖性会导致广泛的业务,技术和社会问题。因此,必须辨别依赖关系,了解其影响,并考虑其他选择。

因此,Bounded Context Design Canvas的最后一部分鼓励您捕获有界上下文的关键依赖关系。

查看您的EventStorm和域流程图,确定您的有限依赖项,并注意以下信息:

  • 其他有界上下文或服务的名称
  • 一个简短的句子解释为什么存在依赖性
  • 依赖所在的位置:此系统内部或外部系统(例如第三方服务)
  • 关系的类型:它是一个传入的依赖(另一个服务依赖于这个有界的上下文),传出(这个有界的上下文取决于另一个),双向或UI(依赖是某种类型的用户界面)

正如您所做的那样,挑战每个依赖项。依赖是否必要?依赖的成本和收益是什么?如果您认为可以避免依赖,请使用小的黄色标记来标记它。

下图是将上面几点汇成一张图表画布:

点击标题进入原文,每个步骤对应图中填写部位。

5. 设计批判

现在你已经完成了画布,花几分钟在你的团队批评你有限的上下文的设计。将您的反馈组织成以下类别:

  • 好:你喜欢的设计方面
  • 坏:你不喜欢的设计方面
  • 不确定:您不确定的设计方面

6. 反思和迭代

好的设计是迭代的。在进入下一个有界背景之前,请退一步看一下大图。你学到了什么挑战你的设计吗?如果有,请立即重新构建您提出的边界,然后继续设计下一个有界上下文。

此时,请问自己是否已对域进行了足够详细的建模。你是否在努力完成画布的各个部分?如果是这样,请考虑在整个域中或在域的某些部分中进行另一轮EventStorming。

5.精炼探索

在为每个有界上下文创建画布并收集设计反馈列表之后,研讨会的下一部分是回归探索。这一次,您拥有高度精炼的知识体系,可帮助您探索更好的设计选择。

此活动的输出是基本上下文映射的集合- 有界上下文之间的结构关系的可视化,以及您认为必要的任何其他图表,如域流故事。每个团队应至少生成三个上下文映射,每个映射都显示系统的替代可能设计。

  • 最后的活动是相当自由的。目标是审查收集的所有信息并将其用于产生多种设计。作为一个起点,我建议:
  • 查看为每个上下文收集的所有反馈,并尝试“糟糕”和“不确定”的反馈
  • 询问“假设”问题......
  • “如果我们将这种能力转移到另一个有界上下文下怎么办?”
  • “如果我们打破这种能力并将其中一个子能力转移到另一个有界上下文中会怎样?”
  • “如果我们将有界上下文分成多个上下文怎么办?”
  • “如果我们从这三种上下文中的每种上下文中获取一种能力并将其用于新的上下文下会怎样?”
  • “如果我们复制功能来破坏依赖性怎么办?”
  • “如果我们创建共享服务以减少跨多个上下文的重复,该怎么办?”
  • “如果我们孤立真正的核心能力并将其他能力转移到一个单独的环境中会怎样?”

5.结束演讲

为了结束研讨会,每个小组应提供他们创建的上下文映射选择,并讨论每个设计的权衡。他们应该解释他们的首选选择和原因。

介于5到10分钟之间通常就足够了。

演示文稿中要考虑的事项:

  • 关注核心领域:每个设计如何更有效地开发系统的核心部分?
  • 比较领域流故事:一个系统设计如何降低复杂性和依赖性数量。
  • 解释接下来要做什么来验证您的首选

 

                   

1