项目的成功始于强有力的探索能力。对于构建新数字产品和服务的团队来说,这通常包括在编写代码行之前进行的用户研究、需求收集和待办事项的创建。但是,如果你的项目是对错综复杂的旧遗留系统进行现代化改造或是将所有工作负载迁移到云上,该怎么办呢?在发布一款新产品时,你如何才能满怀信心地启动项目呢?
本文提供了一种指导方法,通过领域驱动探索(Domain-Driven Discovery,DDD)启动下一个架构现代化项目。为了说明这一点,我们将使用我的一个客户为例,这是一家医疗用品供应公司,它正在将其所有核心系统迁移到云上,并且需要创建一个未来状态架构和实现这一目标的计划。
我们分解了关键步骤和常见的视觉效果,可以让你的团队有信心使用领域驱动设计(Domain-Driven Design)来创建未来状态架构。你可以将本文作为参考来对单个系统或组合系统的架构进行现代化改造。
从探索开始
曾经有一段时间,我们以周期为两周的 Sprint 0 开始新的敏捷项目,然后直接开始编写解决方案。不幸的是,团队后来经常发现他们把时间和金钱浪费在了“把错误的事情改对”上。受设计思维(Design Thinking)和双轨敏捷(Dual-Track Agile)以及像Mobius这样框架的影响,我们集体开阔了视野,认识到了简短探索对产品运营的重要性。
但在过去的五年里,对于各种规模的客户,从初创企业到财富 100 强,我们都已将领域驱动设计应用于它们的架构现代化项目中了。这些经验,再加上对团队培训的投资,帮助我们学会了如何运作有时间限制的 DDD 项目,从而增加了我们架构现代化项目的成功机会。
本文通过四个集成步骤来为你的团队提供架构现代化项目的蓝图:
框定问题——明确你要解决的问题、受影响的人、期望的结果和解决方案的约束。
分析当前状态——探索现有的业务流程和系统架构,以建立改进基线。
探索未来状态——基于有界上下文设计现代化架构,设定战略优先级,评估选项并为未来状态创建解决方案设计。
创建路线图——创建一个计划,随着时间的推移对架构进行现代化改造,并使其与期望的工作流或结果保持一致。
图 1——域驱动探索概述
步骤 0:战略或战术 DDD
在开始之前,确定你的工作等级:
战略 DDD——示例:使用 DDD 对组合系统进行现代化改造。将应用程序迁移到云上,并为复杂的遗留系统创建现代架构。
战术 DDD——示例:使用 DDD 对单个系统进行现代化改造,例如重新构建 Web 应用程序或构建新产品。
根据我们的经验,一个小团队可以在 4-6 周内完成战术 DDD 的探索。战略 DDD 的探索通常需要同一团队 8-12 周的时间才能完成。
探索团队
探索时间表
我们发现,具有时间限制的探索创造了一种专注的紧迫感,可以帮助团队规避分析瘫痪。因为 DDD 使用两周的增量,所以它非常适合现有敏捷团队的日程安排。在开始之前,组建合适的团队,制定时间表,然后开始吧!
步骤 1:框定问题
在架构现代化项目中,经常有很多口头上提到要使用的现代技术,如微服务、无服务器(serverless)、Kubernetes 或服务网格等。人们往往会掩盖他们试图要解决的问题和他们希望实现的结果。但这就是我们应该开始的地方。
以两到三个小时的研讨会开始,围绕一个共享的 Miro 板和一系列练习,要求团队作为一个集体来澄清:
问题——我们要解决什么问题?
人——谁是受影响的人?
成果——成功后会是什么样的?
约束——我们需要考虑哪些约束条件?
对齐这些问题,找到答案至关重要。
对于我们的医疗用品供应客户来说,问题的框定对于定义其核心系统提高弹性和可维护性的成功结果特别有帮助。只需迁移到云上并在多个区域中运行即可解决弹性问题。但是在这一步中,团队开始明白他们还需要提高长期的可维护性,因为他们复杂的架构已经有机地发展了 15 年。
图 2——问题描述、涉众、成果和约束
将你的架构现代化与成果相结合,可以为所有相关人员阐明项目背后的“原因”。 它还建立了改进基线,并鼓励设定目标,这样你就可以随着时间的推移来衡量进展了。
步骤 2:分析现状
框定问题后,你就可以进入第 2 步了。在这一步中,你需要同时关注两件事:业务流程和系统架构。
我们建议使用事件风暴研讨会来阐明与作用系统相关的业务流程。首先选择要关注的主要流程或体验,例如新客户注册。接下来,协同识别该端到端流程中的每个事件。重要的是关注它当前的运作方式,而不是它将来应如何运作。然后确定对流程至关重要的事件子集,并标记这些关键事件。根据经验,仅使用关键事件,你应该就能向外行描述端到端的流程了。
对于战术 DDD 项目,一个单独的研讨会和一些后续的讨论通常就足够了。对于战略 DDD 项目,你可能需要举办多个专注于不同用户和流程的研讨会。我建议在第一周时,从一个研讨会开始,然后根据需要再安排其他研讨会。对于战略 DDD,你不需要详尽地列出整个组织中的每个事件,只需列出足以让你自信地划分与作用系统组合相关的有限上下文即可。
在这些研讨会中,你应该将一种共同的语言与视觉效果配对使用,以使每个人对现今事物的运作方式有一个共同的看法。
例如,这是我们医疗用品客户的事件风暴。图 3 显示了围绕初始客户注册的事件。
图 3——初始客户注册的详细信息
图 4 缩小显示了整个新的客户旅程,其中一些细节被模糊掉了。
图 4——新客户旅程的事件风暴
同时,你应该深入研究当前状态的架构。我们喜欢C4模型,因为它们很简单,建议从某个上下文(C1)关系图开始,将作用系统放在中间,这样你就可以看到包括集成在内的整个生态系统了。
图 5——当前状态的上下文关系图(C1)
接下来,我们将深入到创建容器(C2)关系图,并阐明不同的组件,例如 Web 应用程序、后端服务、数据库和消息传递。与事件风暴一样,这通常是在前两周的研讨会中完成,并根据需要进行后续的调整。尽可能准确地做到这一点至关重要,这样未来的状态建议才能以现实为基础。
对于我们的医疗用品供应客户来说,C2 关系图说明了他们核心系统的复杂性,我们必须要在他们的迁移计划和长期架构现代化中考虑到这一点。图 6 显示了不同角色是如何与连接到订单管理系统的门户进行交互的。
图 6——客户与连接到订单系统的门户进行交互
图 7 缩小显示了生态系统中的所有组件以及它们之间的连接方式。
图 7——当前状态的容器关系图(C2)显示了当前系统的复杂性
至少,我们为每个项目创建了事件风暴、上下文关系图(C1)和容器关系图(C2)。根据项目类型的不同,我们可能需要用额外的视觉效果来对这些进行补充。
步骤 3:探索未来状态
现在你已经对当前状态有了深入的了解,你可以继续执行第 3 步,根据与业务模型一致的有界上下文来创建未来状态。这些有界上下文将指导团队进行架构现代化,并确保技术架构以业务的运作方式为基础。在探索有界上下文时,在业务流程和系统的作用域内寻找高内聚和低耦合的区域。
为此,我们可以克隆事件风暴,然后使用红色标记来识别潜在的有界上下文。图 8 显示了医疗用品供应公司的情况。
图 8——带有草稿上下文的事件风暴
在决定要在哪里划定界限时,关键事件通常会提供线索,但这并不是标准公式。如有疑问,请从较少的上下文开始,然后根据反馈进行调整。在战术 DDD 项目中,我们通常会发现 10 个或更少的面向业务的上下文。对于战略 DDD 项目,我们发现的业务上下文可能是这个数字的两倍或三倍。记住要使用领域专家同意的术语来命名面向业务的上下文,并添加支持性的技术上下文,例如共享服务和分析。
使用消息流细化有界上下文
接下来,我们将创建一个带有消息流的有界上下文关系图,该关系图阐明了如何在上下文之间发送消息。图 9 显示了客户和订单上下文的详细视图:
图 9——客户和订单上下文的详细信息
图 10 缩小显示了组织中所有上下文的鸟瞰图,并用带有编号的消息来说明新客户旅程的步骤。
图 10——带有消息流的有界上下文关系图
DDD 的核心是一个为期一天的研讨会,用于验证步骤 2 和步骤 3 的结果。将这个研讨会安排在项目的中途,并确保邀请领域专家、技术专家和主要利益相关者参与。
在此研讨会中,会发现团队带领参与者了解有界上下文和消息流,一步一个脚印地工作,并与领域专家实时澄清术语。团队将会添加并删除一些箭头。我们应该期待有关命名和事物是如何运作的激烈辩论。在领域专家努力保持一致的同时,技术人员应该将各个点连接起来,确认整个系统是组合在一起的。
在我们的医疗用品供应客户的研讨会上,他们的领域专家建议将收入周期管理(Revenue Cycle Management)拆分到自己的上下文中,而不是将其与付款人(Payer)合并。随后的讨论帮助大家理解了这两种情况之间的差异。我们实时地重新调整消息,最重要的是,整个团队在共享语言和对消息如何在上下文之间流动方面的理解保持了一致。
在解决方案之前先探索选择
架构现代化项目通常从基于企业愿景或战略的总体思路开始的,但从 A 到 B 的方法不止一种,因此有很多选择可供探索。在确定解决方案之前,请先花点时间探索下选择。我们选择的审查广度和分析深度取决于项目的类型和范围以及客户文化,但我们应该为这项工作安排时间。
例如,我们可能会评估是 Amazon Web Services(AWS)还是 Microsoft Azure 更适合我们,或者评估使用云管理的数据库是否比使用在虚拟服务器上运行的数据库更具优势。我们还可以考虑用多种方法来重新构建当前系统和数据库,以便更好地使它们,并与未来状态的有界上下文保持一致。
我总是坚持先有选择再有解决方案,因为这会迫使团队通过多种方式的思考来解决问题。结果通常是每种方法的最佳方面的某种组合,这通常会产生更好的结果。
从战略上对有界上下文进行分类
在 DDD 中,我们喜欢使用核心领域图表来清楚地确定哪些上下文是最重要的战略差异化因素,从而使我们能够相应地调整投资。在这个过程中,我们经常让执行领导参与,以揭示战略洞察力,例如:
我们应该在什么时候构建自定义软件,而不是从市场供应商那里购买?
未来我们应该在哪些方面增加或减少投资?
根据我们的业务战略。我们的上下文将如何随着时间的推移而演进?
我们是否期望基于我们的商业模式或战略出现新的上下文?
我们目前对人员和系统的投资如何与我们的有界上下文相适应?
图 11——上下文的战略性分类
要回答这些问题,请先从模型复杂性和业务差异化的尺度建立今天的基线。在研讨会上,获取新的有界上下文并将它们依次拉入到关系图中,同时调整它们在 x 轴和 y 轴上的相对位置。首先要询问领导者,“你认为你的竞争优势在哪些?”并将这些上下文拉入到关系图的核心(Core)部分上。接下来,问下:“哪些上下文对我们来说不是唯一的?”并将它们拉入到关系图的通用(Generic)部分中。其余上下文属于关系图的支持(Supporting)部分。它们是业务必需品,但提供的投资回报(ROI)有限。添加新上下文时继续调整关系图。最后,引入实验(Experimental)部分来作为一个可能颠覆公司商业模式或行业的大赌注。
如图 11 所示,我们客户的付款人(Payer)上下文是他们的“秘密武器”,也是最大的市场差异化,其次是他们的客户(Customer)上下文。另一方面,收入周期管理(Revenue Cycle Management)很复杂,但并不是他们所独有的。这种洞察力揭示了用供应商的解决方案替换他们自定义的解决方案来提高其核心系统可维护性的机会。
这个研讨会应该是一个民主的过程,其中有很多关于每个上下文在这张关系图上的位置的反复讨论。完成后,我们就有了一个独特的视觉效果,可以战略性地对架构的构建块进行分类:我们的有界上下文。根据我的经验,这通常是主管们“理解”并开始欣赏 DDD 带来清晰度的时候。团队也能从中受益,因为他们了解了构建自定义解决方案的意义所在(核心领域),以及商用现成(COTS)解决方案的意义所在(支持和通用领域)。该研讨会可以帮助我们避免将错误的东西构建成正确的!
使未来状态架构与有界上下文保持一致
确定了上下文并对其进行了战略性分类后,我们就拥有了与业务模型保持一致的未来状态架构构建块。从这里,我们就可以开始将选择转化为解决方案设计了。
在探索过程中,此时所涉及的设计主题高度依赖于我们正在处理的现代化项目的类型。对于像云迁移这样的战略 DDD 项目,我们将关注云基础功能、网络和安全边界以及工作负载的部署。对于战术 DDD 项目,比如创建一个新的 Web 应用程序,我们需要关注微服务、API 和数据模型。
对于我们的医疗用品供应客户,设计的重点是:1)将应用程序迁移到云上;2)将其应用程序重构为与上下文保持一致的微服务,包括数据库、事件消息传递、API 网关和可部署组件等。我们使用容器(C2)关系图来可视化未来状态的样子以及它与当前状态的不同之处。图 12 突出展示了客户和订单上下文相关的组件。
图 12——客户和订单上下文相关的组件
图 13 缩小展示了未来状态架构的所有组件,这些组件与有界上下文保持一致,其中包括跨多个上下文的共享组件,如联邦 API 网关、消息总线和数据仓库。
图 13——未来状态架构的容器图(C2)
本身没有用于创建和改进这些设计的研讨会。我们经常在多个小组会议中研究它们。技术负责人通常通过与提供输入和反馈的客户和专家密切合作来创建这些关系图。我们建议将所有的关系图保存在一个虚拟板上,这样每个人都可以异步地查看它们,并随着设计的演变对其进行评论。我们的团队还应该研究未来设计所考虑的技术能力和限制。
到目前为止,我们一直关注支持业务领域的有界上下文。但是支持组织基础运营的技术服务呢?如何将它们建模为有界上下文的呢?随着时间的推移,我们已经确定了几个应该添加用以支持面向业务的上下文:
共享服务上下文——面向业务上下文使用的通用 DevOps 工具、网络、日志记录、消息传递、监视和其他服务。
安全服务上下文——身份、身份验证和其他安全工具。
分析上下文——数据仓库、分析、数据转换、机器学习、报告和其他数据工具
审计上下文——审计日志记录和合规性工具
有时将网络分离到单独的上下文中是有意义的,有时我们可以简单地将其包含在共享服务中,这取决于我们的基础架构。
设计活动可以很容易地耗完我们分配给它时间,所以一定要将这一步限制在几周内。这段时间足够用于创建未来状态的参考架构,它可以作为起点。我们可以在实施过程中处理剩余的设计决策。目标是到达一个“足够好”的位置,然后继续创建路线图。
步骤 4:制定路线图
实施前的最后一步可以帮助我们定义创建未来状态架构所需的工作、顺序和时间表。我们建议使用一个简单的列表来表示灵活的时间范围(现在-Now、下一个-Next 和以后-Later),而工作流或结果行则表示对工作进行分组的方式,如图 14 所示。
图 14——带有建议的未来状态路线图
对于我们的医疗用品供应客户,我们首先确定了一个重要的里程碑,需要在“现在”阶段结束时完成:他们的所有应用程序都需要“准备好迁移”,他们的云基础必须准备好安全地承载工作负载。就此含义达成一致,并迅速制定路线图的初。锚定这一里程碑有助于帮他们确定在“现在”阶段必须完成的事情,以及可以等到“下一个”和“以后”再做的事情。图 15 显示了路线图上的一些初始项目。
图 15——路线图中“现在”阶段的详细信息
有了路线图草案之后,将其社交化以在审查会议和工作会议期间从利益相关者那里获得反馈。 我们通常在探索阶段结束前两到三周开始制定路线图,这样在向执行涉众展示路线图之前,我们有足够的时间来收集和迭代工作团队的反馈。
阐明架构的演进步骤
DDD 的最后一个阶段是创建架构从当前状态到未来状态演进的清晰视图。我们应该在制定路线图时并行地进行这项工作,因为技术负责人将创建代表架构在“现在”和“下一个”里程碑上的临时状态视觉效果图。团队应该讨论每个可视化效果图,以澄清每个演化步骤中所需的更改,并在工作时修改路线图。
当人们转向领域驱动设计时,我们经常看到反腐模式。这是一个软件层,它将新的基于上下文的有界架构与现有架构隔离开,在我们发展到未来状态时充当有用的桥梁。虽然这一软件生命周期是短暂的,但在我们完成过渡之前,它都可以存在。设计、编码、测试和部署该软件的额外工作为我们提供了从当前状态过渡到未来状态的时间,并减少了一次与重写所有系统相关的风险。
从探索到交付
在短期内,我们的团队可以使用 DDD 来:
明确我们需要解决的问题,受影响的人,期望的结果和解决方案的约束。
分析我们当前的业务流程和系统架构。
确定有界上下文和消息流。
从战略上对上下文进行分类,使投资和决策保持一致。
设计一个与有界上下文保持一致的新的未来状态架构。
创建一个路线图,使当前到未来的状态与业务价值保持一致。
可视化架构的演进步骤。
探索后,我们应该将结果提炼成一个可操作的计划,其中包括(但不限于):
基于路线图构建史诗产品的待办事项。
为“现在“阶段制定发布计划。
设置具有访问权限的开发环境。
对齐团队规范和会议节奏。
进行额外的研究和设计工作,以完善架构。
使用共享的数字白板来完成这项工作可以提供清晰度和透明度,并为以后加入该项目的任何人提供了更简单的入职培训。我目前正在为 DDD 中的所有步骤制作一个 Miro 模板,并将在发布后更新本文的链接。
开始使用 DDD
项目的成功始于强有力的探索能力。在开始另一个架构现代化项目之前,请考虑使用我们的四步 DDD。这种协作方法专为跨职能团队而设计,能以透明的方式将战略与架构结合起来,同时为领导者和技术人员构建了一种共享语言。在短期内,你即可获得清晰的洞察力来指导你的项目,这将有助于节省时间、精力和金钱。
原文链接:
https://www.infoq.com/articles/architecture-modernization-domain-driven-discovery/
评论 2 条评论