领域驱动设计兑现承诺了吗?


“解决软件核心的复杂性” ——DDD 能成功兑现这个承诺吗?

为了诚实地回答这个问题:DDD 有助于降低复杂性吗?,我根据四个因素开发了一个个人的复杂性心理模型:F1-F4。在我看来,复杂性可以在以下情况下得到控制:

  • 问题空间正确(足够好)映射到解决方案空间(又名“建模”已正确完成)。
  • 我们有一种“分治”的方法(将模型“水平”组织成相对独立的部分)。
  • 我们能够在“整体”上导航(包括垂直遍历 - 就像谷歌地图一样),动态调整细节水平。
  • 我们已经建立了一种长期维护该模型的方法。

这四个因素实际上意味着什么,为什么它们如此重要?

建模
我们制造的产品无法以完全反映现实为目的。因为物理现实是无限复杂的,它的大部分细节都是噪音和干扰因素。
我们需要的是经过简化和过滤的版本:现实中与当前环境相关的部分(/方面)。
DDD 将其称为 "模型"。

但没有一种方法可以模拟现实。

甚至没有一种方法能做到完美。有很多 "足够好 "的方法,而整个挑战就在于找到其中一种,这就是我所说的 "适当/正确的建模"。

在宣传建模的重要性方面,DDD 做了很多有益的工作:

  • 强调领域(问题空间)和模型(解决方案空间)之间的区别
  • 提供非常有用的(子)领域分类法
  • 引入一个术语--泛在语言(UL)--作为正确表达模型的一种方式(其含义是:如果模型反映在 UL 中,模型与解决方案(代码)1:1 地映射,并且变更也用 UL 来表述,那么变更的实施就会带来尽可能少的摩擦和几乎零的浪费)。
  • 尽管 EventStorming 并不是 DDD 的 "核心 "部分,但它是一种能极大帮助 "挖掘 "建模输入的技术。

因此,看起来 DDD 在这里提供了一个很好的基础。然而,我无法摆脱的印象是,为建模添加一些形式和结构的使命还没有真正开始就被放弃了。为什么会这样呢?

  • 如何区分好模型和坏(/有缺陷)模型?模型的质量功能是什么?
  • 表达模型的好方法(/建议)是什么?(以便于共享和协作)
  • 我喜欢 DDD 强调通过与领域专家直接合作来获取知识。然而,这些 "原始 "知识最初是非结构化和无序的:有什么建议的启发式方法来构建这些知识?

因此,在建模过程中,我们几乎只能依靠本能、直觉和我们独特的经验(我们以前见过的模式和心智模型)--DDD 在这方面帮不了我们什么(通过 "包装 "这些知识以供重复使用)。

模型不是用 UL 表达的专家大脑的原始数据,经典的 DIKW(数据-信息-知识-智慧)金字塔在这里也适用:模型是这个处理管道的最后阶段。

分而治之
有些领域由于其 "规模"--涉及概念的数量及其相互依存关系的多样性--而非常复杂。在某些时候,认知负荷开始成为一种负担:即使是最聪明的人也无法覆盖整个模型。

首先是没有注意到风险、模式、机会或冗余。这导致了挫败感、随后的错误和一些临时的防御策略,为我们赢得了一些时间,但也换来了严重的(模型)债务,进一步加速了复杂性的增长。

这就是为什么解决方案空间("大象")必须被分割成相对独立的部分,这些部分可以(或多或少)分开拥有、维护和开发。这种分割是软件设计与开发中最具挑战性的课题之一。

遗憾的是,领域驱动设计在这里帮不了我们什么。

DDD 并非让我们完全一无所获。我们有了 "有界上下文BC"、"服务"(无状态业务逻辑)和 "聚合"(具有业务逻辑的实体集合)
但这些心智模型还远远不够。
感觉上,这是作者(埃里克-埃文斯)的第一个直观(和 "未出炉")的想法,但由于它已经印刷出来(在 "蓝皮书 "中),所以他从来不敢对它进行迭代和改进。

我对这些概念有什么意见?

  • "有界上下文BC "是一个革命性的概念,其定义极其模糊:它是模型的一部分,UL 在其边界内是一致的,它直观地聚合了合作群体(具有共同关注点)意识中存在的焦点概念--仅此而已。它非常主观,依赖于观点,而非事实/测量。
  • 有界语境BC 是非常高层次的,而 "服务"、"聚合 "和 "实体 "则是非常低层次的。遗憾的是,实际的挑战在于如何组织区域/模块/应用,以便将本应属于一起的概念和功能组合在一起,DDD 并没有(甚至没有尝试)就如何做到这一点给出明确的指导。在最需要分组的中层,也没有相应的分组概念。
  • 坦率地说,"蓝皮书 "中提到了耦合和内聚的概念,但更像是松散的指导,而不是试图为构建模型创建一个规范性的基础。这可能是一个正确方向上的提示,但随后却没有任何行动。

这似乎又一次浪费了机会。如果摒弃领域服务、聚合或实体等低级(且相对无用)概念,同时精心选择承诺理论(合同!)、耦合与内聚二分法的科学方法或领域语义分析(术语的概念 "接近性"、"能力 "的定义等)等元素,那么 DDD 本可以做得更好。

如果不这样做,我们就会一直在这样的日常挑战中挣扎:

  • 折扣 "应该是 "项目定价 "的一部分吗?取决于它?还是相反?还有 "购物车折扣"?还有 "数量折扣"?还有......
  • 组织快递递送的最佳方式是什么?围绕 "快递可用性"、"路线"、"预定递送 "还是 "附近可用性"(这是对相同数据的四种不同视角)?