【问题标题】:Querying distinct values in Aggregate subset in Domain Driven Design?在域驱动设计中查询聚合子集中的不同值?
【发布时间】:2018-05-22 17:52:31
【问题描述】:

假设我有一个聚合,Foo。该聚合由数据库中的一个简单平面表表示...

Foo
------------------------------
| id | prop1 | prop2 | prop3 |
| 1  | a     | b     | c     |
| 2  | a     | bb    | cb    |
| 3  | ac    | bc    | cc    |
------------------------------

现在我想在前端过滤 Foo。我有一个表单,需要将 foo 的不同属性显示为列表并从中进行选择。选择属性后,我需要查询 Foo 并找到具有所选属性的行子集。然后我需要为搜索查询选择的行子集中的每个属性选择不同的值。

例如,假设用户选择a 作为prop1 的值...

SELECT DISTINCT * FROM Foo WHERE prop1 = 'a';

在 DDD 中对此建模的适当方法是什么?我的第一个想法是创建一个完全独立的聚合,用于对上述查询或类似查询的结果进行建模......

class DistinctFooProperties
{
  private $prop1;
  private $prop2;
  private $prop3;
  public function __construct(
    StringCollection $prop1,
    StringCollection $prop2,
    StringCollection $prop3
  ) {
    $this->prop1 = $prop1;
    $this->prop2 = $prop2;
    $this->prop3 = $prop3;
  }
  public function getProp1Possiblities() {
    return $this->prop1;
  }
  public function getProp2Possiblities() {
    return $this->prop2;
  }
  public function getProp3Possiblities() {
    return $this->prop3;
  }
}

class DistinctFooPropertiesMySQLMapper
{
  public function findBySearchObject(FooSearchjObject $fooSearch) {
    // Search and return DistinctFooProperties
  }
}

这会导致一些复杂性。 DistinctFooPropertiesFooSearchObject 将非常接近地反映 Foo 聚合的属性,但远远不够,我想不出一个接口来强制它们都应该谈论相同的属性。

有解决这个问题的标准方法吗?

【问题讨论】:

    标签: search model domain-driven-design aggregate distinct-values


    【解决方案1】:

    我的第一个想法是创建一个完全独立的聚合,用于对上述查询或类似查询的结果进行建模。

    如果您只需要查找其他聚合或其属性,则无需创建聚合。为此,您可以创建域服务,其接口在域层中定义,实现在基础设施层中。他们的方法可能会返回值对象(如DistinctFooProperties),甚至是完全加载的聚合,具体取决于它们的用途。

    作为一个侧节点,查询 SELECT DISTINCT * FROM Foo WHERE prop1 = 'a'; 将始终返回不同的行,如果 id 是唯一的,则无论是否带有 DISTINCT

    【讨论】:

    • 那么你会在域层以外的层中进行这个查询吗? o.O
    • @Allenph 当然。域不应该知道基础设施,而 SQL 是非常基础设施。
    • 我以为所有的服务都在应用层?我猜你会有一个代表搜索参数的值对象和一个代表结果的结果对象,然后是一个类似于映射器的“服务”?似乎是一个不称为聚合的聚合。
    • @Allenph 应用程序服务负责事务和加载/保存到持久性
    • 我使用应用程序服务进行事务处理,但不是聚合的 DDD 有界上下文以及它们的映射器/存储库的很大一部分吗?我想我现在明白你的意思了。似乎该查询属于基础设施层的某个地方,然后应该在服务层中调用,不是吗?
    【解决方案2】:

    您可以使用某种generic Specification,尽管根据您的上下文,将其映射到 SQL 可能或多或少复杂。我相信 PHP 是一种具有足够可塑性的语言,但它不会太难。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      • 2013-09-16
      相关资源
      最近更新 更多