【问题标题】:Aggregate - Correct Usage (DDD)聚合 - 正确使用 (DDD)
【发布时间】:2015-04-05 19:20:54
【问题描述】:

我一直在尝试开始使用领域驱动设计 (DDD),因此我已经研究了一段时间。我有一个问题,我寻求有关如何以 DDD 方式解决它的帮助。

我有一个 Client 类,它包含大量的属性 - 其中一些是简单的属性,例如 string contactName 而其他的则是复杂的,例如列出地址、列出网站等

DDD 主张 Client 应该是一个实体,它也应该是一个聚合根 - 即,客户端代码应该只操纵 Client 对象本身,它可以归结为Client 对象对其内部对象(地址、网站、名称等)执行操作。

这就是我感到困惑的地方:

应用程序中有大量的业务规则依赖于客户端的内部对象——例如:

  1. 根据客户的出生或居住国家/地区及其地址,某些 FATCA(美国法规)限制可能适用。
  2. 我需要使用来自其他系统的数据来丰富一些内部对象,包括我组织内部和外部的数据。
  3. 应用程序必须决定是否允许 客户端 执行操作,为此,应用程序需要仔细检查大量客户端详细信息并做出决定 - 此外,当应用程序仔细检查时Client 它需要更新其许多属性以跟踪导致应用程序做出该决定的原因。
  4. 我可以在这里列出数百条规则 - 但你明白了。我的观点是我需要更新许多 Client 的内部属性。从域的角度来看,根是 Client - 它是用户在 GUI 中搜索的 Client。用户只关心整个客户。比如说,一个孤立的地址是没有意义的——它只有在它是 Client 的一部分时才存在。

说了这么多,我的问题是:

Eric Evans 说根可以返回对内部对象的瞬态引用,最好是 VO(这里的关键字:VO) - 但是对内部对象的任何操作都应该由根本身执行。

我需要在我的客户端上执行数百个操作 - 如果我将它们全部移到根目录,根目录将会变得很大 - 它至少有 10K 行代码!

根据 Eric 的说法,VO 应该是不可变的 - 因此,如果我的根返回 VO,则不允许客户端代码更改它们。所以在服务中做这样的事情是不可接受的:client.getExternalInfo().update(getDataFromExternalSystem())

所以我的问题归结为到底我应该如何在不违反 DDD 规则的情况下更新内部对象?

我看不出有什么简单的出路。


更新一:

我刚刚遇到规范,这似乎是解决我的问题的理想 DDD 概念。

我仍在阅读它,但我还是决定发布此更新。

【问题讨论】:

    标签: oop domain-driven-design


    【解决方案1】:

    我自己已经学习了一段时间 DDD,并且正在努力掌握它。

    首先,您是对的:规范是一个很好的模式,通常用于验证或业务规则,假设您应用的规则与谓词树非常吻合。

    当然,我不知道您的设计细节,但我确实想知道模型本身。您提到您的 Client 类具有“很多属性”。你确定你的模型不是anemic吗?您的设计能否从更多分析中受益,或许将其分解为其他聚合?这是一个单一的有界上下文吗? 应该是吗?

    【讨论】:

    • 感谢您抽出宝贵时间回答我。现在它很贫乏——事实上,应用程序很大(而且有点旧),实体都是 getter 和 setter 的包。对对象的操作由服务执行。这不太正确,这也是我考虑如何移动服务代码以及应该将其放置在何处的原因之一。关于不止一个聚合:我不这么认为,但我确实需要再考虑一下——感觉应该有。嗯,是的,它是一个单一的有界 ctx - 但我想我需要再次考虑一下。
    • 我明天将在办公室提出这个讨论,我将根据我们对此事的见解更新问题。
    【解决方案2】:

    规范绝对是解决复杂业务逻辑的方法。

    但有一个问题 - 您是否将内部实体(如地址和名称)建模为 ValueObject?我能想到的最好的经验法则是,如果你可以说它们是相等的,没有 ID,它们很可能是值对象。您的域名是否认为名称具有状态?

    如果您遇到的问题是很少有实体接受多种类型的更改并且需要审计跟踪,那么您可能还想探索 EventSourcing。理想情况下,实体声明其对事件的反应,但您也可以将变异代码保存在事件中以便于扩展。当然,这种方法有利有弊。

    【讨论】:

      猜你喜欢
      • 2018-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-25
      • 2016-03-21
      • 1970-01-01
      相关资源
      最近更新 更多