【问题标题】:DDD referencing large data sets / injecting repository?DDD 引用大型数据集/注入存储库?
【发布时间】:2014-06-24 15:24:10
【问题描述】:

我正在努力寻找以下问题的最佳解决方案。我需要确定某个国家/地区是否为“InUse”(例如当前由地址引用)。

我在 NHibernate 中映射了以下简化模型:

class Address
{
  public Country Country {get; set;}
}

class Country
{
  public List<Address> Addresses {get; set;}

  bool IsInUse()
  {
    return Addresses.Any();
  }
}

对 Country 使用 IsInUse 方法效率低下,因为它会导致所有国家/地区的负载(.Any() 在内存中执行)。此外, Country 并不需要真正了解 Addresses,它纯粹是为 IsInUse 方法而存在的。所以,从消费者的角度来看,我喜欢上面的例子,感觉域对象应该暴露一个 IsInUse 方法,但它不会执行并且包含不必要的关系。

我能想到的其他选择是;

  1. 只需使用存储库并直接从服务层调用它。存储库可以封装仅发出 SELECT COUNT(*) 的调用,而不是 SELECT *,就像上面的延迟加载选项一样。此选项将 IsInUse 逻辑完全置于域层之外。
  2. 将存储库注入 IsInUse(),调用与上述相同。我读到这是非常糟糕的 DDD 实践。

有没有人对此问题有任何建议或更好的解决方案。

希望以上内容有意义...谢谢。

【问题讨论】:

    标签: domain-driven-design repository-pattern


    【解决方案1】:

    我建议您不要在每次执行查询时都计算它。非规范化 IsInUse。每次从某个国家/地区添加或删除地址时,您都可以确定该国家/地区是否正在使用并保存该值。

    如何确定该值是另一回事,有多种技术,从保存地址时立即确定,到更新国家/地区的 IsInUse 值,甚至在这些恰好是不同 BC 的实体时使用消息传递。

    【讨论】:

      【解决方案2】:

      感觉就像您正在编造领域概念来解决您的问题。你能告诉我们为什么你需要知道一个国家是否在使用吗?

      存储库非常适合捕获语言和聚合持久性,而不是用于查询。你基本上是在问你的数据一个问题。也许将这个逻辑完全移到查询端?另见http://www.jefclaes.be/2014/01/repositories-where-did-we-go-wrong_26.html

      也许还有另一种方法可以跟踪所有使用中的国家/地区。这些地址来自哪里?也许您可以引入域事件 - 一个地址被注册时,将该国家添加到正在使用的国家列表中,这样您就可以查询一个较小的列表。

      【讨论】:

      • 感谢您迄今为止的回复。原则上我需要知道对象是否在使用中,以便确定它是否可以编辑或删除(国家示例不是我的真实代码,为了简单起见,我使用国家,但原则上假设国家不能更改,如果它正在使用中)。谢谢。
      【解决方案3】:

      我会在没有来自 NHibernate 或任何其他持久性机制的概念的情况下设计您的域实体。如果这意味着通过使用 NHibernate,您需要引入 2 路映射属性作为标准,那么我只会在您的存储库中使用您的 NHibernate 实体,并为您的域模型设计一组单独的实体并在两者之间进行映射。从您的企业的角度来看,我认为Country 不应该对Address 有任何了解,这似乎是合理的。

      将存储库注入您的域实体或使用延迟加载通常会违反 DDD,并在您序列化实体或它们丢失数据库上下文时导致问题。

      您的IsInUse 问题可以通过缓存查询来解决(并非所有东西都必须在存储库中),也许您可​​以创建一个处理这个问题的CountryStatistics 类?或者,您可以保留一个单独的持久国家/地区列表,每次使用以前从未使用过的国家/地区创建新地址时,该列表都会更新。

      【讨论】:

        猜你喜欢
        • 2015-01-03
        • 2021-10-11
        • 2016-05-01
        • 1970-01-01
        • 2012-01-27
        • 2014-10-28
        • 1970-01-01
        • 2010-11-24
        • 1970-01-01
        相关资源
        最近更新 更多