DDD有界的上下文和域?


16

我一直在一个相对复杂的应用程序中,该应用程序具有10多个数据库表(聚合,实体/值对象)并应用DDD。此时,它似乎基本上是DDD-Lite,这意味着有应用程序/域服务,域模型(实体,值对象)和存储库。

我拿起一本书《实现DDD》,他首先提到的是DDD-Lite和Bounded Contexts和Domain Events缺失,这是开始DDD时常见的第一个错误。

目前,我已经尝试通过聚合关系来组织域模型,并使用名称空间进行演示。

我没有看到与将域模型项目划分到单独的有界上下文中有关的好处/缺点(尚未)。也许稍后会变得很明显,但我希望获得有关绑定上下文(以及可能绑定到子域等的一些现实生活)的反馈。


在我看来,定义单独的有界上下文的唯一一件事就是需要区分语言学和相关的操作差异,即在一个领域中称为产品,在另一领域中称为产品,但是它们是不同的,因此我们需要两种产品,并且两者都可以。型号相同(名称相同)。那么,为什么我们不只是更改名称来表示它们微妙的语义呢?他们可以有一个模型来统治所有的人。子域是自然的,但目前我看不到有限的上下文。只是在这里大声思考...
Ashley Aitken

我猜您已经意识到为什么在上下文中拆分域名是有利可图的。因此,现在有用的是识别它们,定义上下文边界的正确方法。这是我的操作方法:medium.com/@wrong.about/…–
Zapadlo

Answers:


20

考虑一个有几个不同部门的公司:

  • 软件开发
  • 人力资源
  • 会计

您能否提出一个可以表达所有业务领域的用户模型?考虑一下用户实体在每个实体中的外观。也许它分为三个不同的实体:

  • 开发者
  • 雇员
  • 收款人

在每种情况下实例化用户的工作都大不相同。也许是这样的:

  • 新员工(ssn,姓名,加入日期,生日,性别)
  • 新开发人员(员工,工作站,凭据)
  • 新收款人(员工,角色)

请原谅这个例子,如果没有合适的领域模型来参考就很难准确说明

如果您使用一个简单的实现并使用单个用户实体,则最终将是一个充满getter和setter的贫乏数据模型,因为您不能完全代表整个地方的用户。

业务中存在明确的界限,因此以这种方式进行建模很有用。登录用户与工资系统中的用户与玩游戏的用户,即使它们是同一盛大系统的一部分,也大不相同。

用另一种方式思考-您现在可以创建开发人员管理代码,使其轻巧且独立于系统其余部分。它可以使用更准确的类型,而无需担心的行李少。这是构建较小的子系统的步骤,该子系统最终可能会提取到其自己的应用程序中。


感谢您的支持示例,该示例有助于说明3 BC的不同需求。
lko

不是我习惯于看到这些概念的方式:通常,an Employee不是a User,它具有 a User。在User简单地通过一个人可以登录和访问一个或组织内部的多个应用程序的实体。和Employee并不总是有一个User。另外,通常您不会获得针对不同部门的简单应用程序;通常,每个部门都有自己的应用程序,每个应用程序都包含自己的域模型。因此,对我来说,此答案无助于阐明在同一代码库中具有单独的有界上下文的需求。
罗杰里奥

@Rogério,您的反对实际上是一个很好的例子,它说明了正确定义每个有界上下文中使用的无处不在的语言很重要的原因:)
MauganRa

我只是想知道在以下情况下:我们是否拥有客户管理系统,何时打电话查询订单或开具发票等?我们在转移到相应部门的同时被搁置了。每个部门的领域知识都将发挥作用-在这种情况下,客户的烦恼极大。也许我们可以责怪DDD强制将这些上下文分开。
安德兹(Andez)'17

16

我可以再举一个例子。考虑您有一些电子商务系统。您将在那里拥有产品,但是产品将至少属于两个不同的域:

  • 产品目录,您可以在其中保留产品说明和所有属性
  • 库存,您拥有产品库存水平

如果两个域都有一个有限的上下文,则您的解决方案很快就会变成一个泥潭,因为您将开始对其进行交叉引用。最后,您将不再有两个域。产品目录参考会破坏您的产品库存,反之亦然。结果,即使您完全意识到这不是必需的,您也将无法更改一个域而不接触另一个域。您的模型彼此依赖并紧密耦合,并且相互依赖的方式非常糟糕-依赖于实现。

但是,如果您有两个有限的上下文,则在保持沟通渠道畅通后,您在一个域中所做的所有更改都不会影响另一域。这将意味着您需要进行数据重复,但这是为基于组件的丢失耦合应用程序支付的最低成本。您的域可以使用域事件相互对话。即使您不打算在一开始就拥有基于SOA的应用程序,您也可以在需要时以相对较少的精力将其扩展到该级别,因为您只需更改域事件的传输方式,就可以保留其思想。

更新:埃里克·埃文斯(Eric Evans)在SkillsMatter上有一个很好的技能演示。当几个盲人从大象的角度描述大象时,他给了这个古老的故事一个比喻。由于每个人只能触摸大象的一部分,因此他们将其描述为“树”,“墙”,“蛇”,“绳子”。这些人中的每个人都是正确的。有限的上下文是无处不在的语言赖以生存的地方。在上下文之外,这些术语可能具有完全不同的含义,但是在上下文内部,跨多个领域使用的语言是相同的。格雷格·杨(Greg Young)强烈建议从第11章开始阅读蓝皮书,因为其中解释了最重要的基本概念。本书开始时就以战术模式为重点,因此这种“ DDD-light”方法非常普遍,


1
+1也会引起重复。这是一个有点在第一混乱(“我这样做不对?!),但它是完全自然的,任何在许多情况下,必须的。
阿德里安·施耐德

在这种情况下,这些Product类是否都假设都共享相同的ID(例如,两个单独的BC表都具有指向具有单个Product ID的表的外键)?也许在与Domain Events通信时,他们可以使用该ID?
lko

1
这完全取决于选择什么存储。无需使用技术ID来引用跨域。也不建议进行跨上下文通信。
Alexey Zimarev 2014年

1
看来是时候把蓝皮书从书架上
拿下来
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.