DDD中如何借助行业术语突破性发现领域模型? - Mathias


早期面向对象设计OOAD是通过发现名词来发现寻找对象,今天,我们不提倡使用名词发现法来简单地模拟现实世界中的事物,现实要复杂得多。找到好的对象意味着识别属于应用程序域及其执行机制的抽象。他们与现实世界事物的对应充其量可能是微不足道的。即使在对领域概念进行建模时,您也需要仔细查看这些对象如何适应您的整体应用程序设计。 —对象设计,Rebecca Wirfs-Brock
早面向对象设计的核心是从 A 到 B 的线性路径(线性思维=一根筋):

  1. 了解问题,
  2. 应用设计,
  3. 最终得到一个解决方案。

(线性思维: 问题空间=> 解决方案空间 )

领域语言与无处不在的统一语言
这个想法也一直存在于领域驱动设计的许多幼稚的解释中。领域语言(行业术语)和无处不在的统一语言(Ubiquitous Language )经常被混为一谈。他们是不一样的。
领域语言是在领域工作的人使用的语言。这是一种自然语言,因此很混乱。它是有机的:概念的引入是出于需要,没有经过深思熟虑,没有达成一致,没有精确。术语在整个组织中传播或逐渐消失。意义转变。人们将旧术语改编成新含义,或者术语获得了多重、含糊不清的含义。它存在是因为它有效,至少对于人与人之间的交流来说足够好。领域语言(像所有语言一样)只能在它进化的特定上下文中工作。
对于我们系统设计师来说,乱七八糟的语言是不够的。我们需要具有易于理解的概念和明确上下文的精确语言。这就是无处不在的语言:一种构建的、形式化的语言,由利益相关者和设计师同意,以满足我们的设计需求。与领域语言相比,我们需要更多地控制这种语言。统一语言必须和领域语言有很深的联系,否则就会出现不和谐。
任何通用语言的正式程度和精确度取决于其环境上下文:例如:共享应用程序和石油钻井平台控制系统有不同的需求。
 
石油钻井平台 
Rebecca 受邀为一家为石油钻井平台制造硬件和软件的公司提供咨询。她被要求帮助进行对象设计和建模,致力于重新设计监控和管理石油钻井平台上的传感器和设备的控制系统。钻孔会产生很大的摩擦,“钻井泥浆”(一种专有化学物质)被用作润滑剂。它还用作您从钻孔中获得的岩石和碎屑的载体,将它们全部提起并从孔中取出。设备监测钻井泥浆压力,通过在钻井过程中改变泥浆的成分,您可以控制该压力。压力太大真的是件坏事。
然后海湾中的一个石油钻井平台爆炸了。
随着新闻报道的出现,该团队发现该钻机正在使用竞争对手的设备。哇!团队开始推测可能发生的事情,并考虑如何在他们自己的系统中发生类似的事情。是设备、传感器、遥测、各种组件之间的通信、软件有问题吗?
  
上下文场景情形
团队研究了当时发生灾难的场景。当灾难性情况发生了什么?人们如何反应?当出现故障时,对于石油钻井平台工程师来说,这是一个嘈杂的环境:警报器响起,警报响起,......尽管。当故障很容易修复时,控制系统日志会反映警报持续发生并在几分钟后关闭。
但是对于更严重的故障,即使这些问题需要更长的时间来解决,它仍然会在日志中显示为在几分钟内解决。然后,当人们研究日志时,看起来故障很快就解决了。但这完全不准确。这可能看起来像一个软件错误,但它实际上是模型中的一个缺陷。我们应该利用它作为改进该模型的机会。
最初的建模假设是警报与现实中的紧急情况直接相关。然而,系统对世界的感知是扭曲的:当工程师关闭警报时,系统认为紧急情况已经结束。但事实并非如此,关闭警报并不会改变世界上的紧急情况。警报仅与紧急情况间接相关。如果它是间接连接的,则介于两者之间的其他东西,在我们的模型中不存在。该模型是对世界事实的不完整表示,这可能是灾难性的。
 
“向真正深度模型的过渡是你思维的一次深刻转变,需要对设计进行重大改变。” —领域驱动设计,埃里克·埃文斯
  
突破
团队探索了一些场景情形,特别是奇怪的情形、尴尬的边缘情况,没有人真正知道系统的行为方式,甚至不知道它应该如何行为。一种这样的场景情形是当两个单独的传感器测量同时发出警报时。警报响起,工程师将其关闭,但是第二个警报会发生什么?警报是否仍应响起?应该关闭一个就关闭另一个警报?如果它没有关闭,工程师会认为关闭开关不起作用并再次按下它吗?
通过处理这些场景情形,该团队发现警报响起和警觉状态之间存在区别。现在,在这个新模型中,当传感器的测量值超过特定阈值或表现出特定模式时,系统不再直接发出警报。相反,它会引发警报条件,该条件也会被记录。正是这种与实际问题相关的警报条件。新的警报概念现在负责发出警报(或不发出警报)。警报仍然可以关闭,但警报条件仍然存在。具有不同原因的两种警报条件可以共存,而不会被单一警报混淆。该模型将紧急情况与警报声分离。
旧模型没有做出这种区分,因此它不能很好地处理边缘情况。当团队终于明白需要将警报条件与警报分开时,他们无法忽视它,这种区别并不容易被发现。这就是埃里克·埃文斯所说的突破。
 
创造之举
有一个缺失的概念,起初团队不知道缺少什么。起初并不明显,因为在领域语言中(行业术语)没有“警报条件”这个名称。石油钻井平台工程师的工作不是设计软件或创建精确的语言,他们只是希望能够平静地响应警报并解决问题。规范文件或石油钻井平台工程师之间的任何通信中也都没有出现警报条件。工程师或软件并未暗中使用该概念;不,整个概念不存在。
那么这个概念是怎么来的呢?
该领域的人遇到过这个问题,只是没有明确的术语,他们无法向系统设计者表达这个问题。所以必须由我们设计师创造它。这是一种创造性的建模行为。这个概念是发明出来的。在我们的石油钻井平台监控领域,这是一种感知现实的新方法。
当然,在英语中,alert 和alarm 是存在的。它们几乎是同义词。但是在我们无处不在的语言中,我们同意让它们与众不同。我们设计了同意语言( Ubiquitous Language) 来满足我们的目的,它不同于领域语言这些行业术语。在我们引入“警报条件”之后,石油钻井平台工程师同意将其纳入他们的语言中。
领域中的这种变化是由设计驱动的这打破了通过设计从问题到解决方案的线性、单向理解。相反,通过设计,我们重新定义了问题。
 
它是一个更好的模型吗?
我们怎么知道这个新发明的模型实际上更好(具体来说,更适合目的)?我们找到现实场景并针对警报条件模型以及其他候选模型对其进行测试。在我们的例子中,使用新模型,日志会更准确,这是原始最初问题爆发所在。
但除了有助于解决最初的问题之外,更深层次的模型通常会带来新的可能性。该警报条件模型提出了几个建议:

  • 不同的测量可以与相同的警报相关联。
  • 警报条件可以被限定。
  • 我们可以为同时出现的警报条件定义警报行为,例如通过间隔警报或选择不同的声音模式。
  • 严重警报可以阻止不太重要的警报占用警报。
  • 随着情况的改善,警报条件可以降低,而无需解决它们。

这些新选项是相关的,并且可能带来价值。我们找到更好模型的另一个迹象是我们与领域专家进行了新的对话。许多故障场景变得更容易检测和响应。我们开始问,可能存在哪些其他警报条件?我们还没有降低哪些风险?我们应该如何反应?
 
设计创造新现实
在以现实世界为中心的设计视图中,现实世界中只存在传感器和警报,而旧的软件模型准确地反映了这一点。因此,这是一个准确的模型。包含警报的新模型并不比旧模型更“准确”,它不是来自现实世界,也不是更现实,也不是更“领域化”。但它更有用。与警报条件相比,传感器和警报是客观的。某些事情是一种警报条件,因为在这种环境中,我们认为它应该是一种警报条件,这是主观的。
该模型适用于领域,并能连接到它,但它不是一个单纯的模型的问题域。它解决了我们更好地设想的上下文中的问题。该解决方案澄清了问题。只关注现实世界的建模会使我们对更好的选择和创新视而不见。
在有关建模的文献中很少讨论这些将新概念创造性地引入模型中。软件设计书籍谈论将概念转化为类型和数据结构,但如果概念还没有呢?然而,形成区别,而不仅仅是抽象,可以帮助澄清模型。这些区别创造了机会。
该模型必须从根本上考虑其在解决问题中的效用。