【问题标题】:How should I design DDD aggregate with an invariant based on information from multiple aggregates?我应该如何根据来自多个聚合的信息设计具有不变量的 DDD 聚合?
【发布时间】:2022-01-24 02:13:00
【问题描述】:

我是域驱动设计的新手,完全被建模问题困扰。这是一个只有一个不变量的简单特性的设计级事件风暴的截图: 让我们假设证书的条件不允许最终一致性,并且立即满足此条件以处理订单是绝对关键的。在这种情况下,要检查我的证书不变量,我需要访问:

  • 订单季节
  • 供应商所在国家/地区
  • 针对特定国家/地区检查证书的季节
  • 供应商的证书以及它们是否被接受并且是最新的

最初我尝试将我的应用程序拆分为多个有界上下文,对我来说,这些信息属于不同的有界上下文。然后我是否应该将所有这些必要的数据(上面列出的)放在一个聚合中以确保一致性并使其相当大,或者是否有任何其他解决方案?也许我的整个推理都是错误的,而且没有多大意义?也许有界上下文边界是错误的,因为需要将数据到达其他上下文(不是自治的)?也许域服务可能是一个解决方案?我将非常感谢任何帮助,因为我对那些 ddd 主题感到很困惑:/

【问题讨论】:

  • 据我所知,从有限的信息来看,您基本上有两个不同的“证书”对象:一个在证书(管理)上下文中,一个在订单处理(验证)上下文中,它做完全不同的事情。因此,真正的问题是,如何将管理上下文的变化分配给验证上下文中不同证书的变化?有多种选择,但我建议您查看域事件 (serialized.io/ddd/domain-event)。
  • 请注意,走领域事件路线意味着最终的一致性,出于本问题的目的,这已被排除在外。
  • 您能否提供有关您的聚合的更多详细信息?您的案例中涉及哪些聚合,以及您的设计中的聚合位于哪些有界上下文中?一般来说,如果在不同的有界上下文中涉及聚合(或数据),那么如果最终一致性需要强一致性,那么实现起来就会变得更加复杂......

标签: aggregate domain-driven-design modeling bounded-contexts


【解决方案1】:

在回答您的问题之前,我建议您记住以下陈述:

  1. 在 Aggregate 中整合您的业务不变量(规则)。
  2. 如果可能,设计小型和自主的聚合。
  3. 使用其 ID 引用其他聚合。
  4. 使用最终一致性更新其他聚合。

现在让我分享我的观点并给你建议(我在下面的代码 sn-ps 中使用了 C# 语法

我建议您使用 2 BC - OrderSupplier,它们中的每一个都是单独聚合的良好候选者。 Certificate 不是聚合,我们可以通过供应商聚合访问它。

前言:我们有 2 个服务,-Order application service 注入存储库接口以检索特定数据。此外,我们有一个Order domain service,我们正在使用我们的聚合。

现在,如果您想检查证书不变量,请执行以下步骤 -

  • 我们应该通过从存储库中提取数据来安排订单应用服务中所有需要的数据

  • 现在是验证的时候了 (supplier's certificates and if they are accepted and up to date) 证书不变量。

  • 让我们切换到订单域服务来决定订单处理,我们有下一个方法public void AddOrder(Order newOrder, Supplier supplier)

    • 但是让我们从添加类似的具体业务规则类开始
    public class SupplierCertificatesAreValidRule{ 
    public SupplierCertificatesAreValidRule(IList<Certificate> supplierCertificates){
    ...

    }
    
    public bool IsValid() {...}
    }
  • 从供应商实体集合中获取其证书。
  • 让我们定义订单的季节
  • 然后获取供应商所在的国家/地区
  • 获取season from which certificates are checked for specific country
  • 在 Order 实体本身中添加 Add 方法,在此方法的开头我们应该这样调用我们的业务规则:
public static Order Add(Order newOrder, Supplier supplier){
CheckRule(new SupplierCertificatesAreValidRule(supplier.Certificates));
return new Order();
}
  • 如果规则不符合,那么我们应该抛出一些业务规则验证异常并在那里解释原因。
  • 如果我们的规则得到满足,那么这意味着我们可以处理我们的订单

【讨论】:

    猜你喜欢
    • 2019-08-07
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 2016-11-29
    • 2020-09-03
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    相关资源
    最近更新 更多