Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Domain driven design 使用存储库模式保存复杂聚合_Domain Driven Design_Repository Pattern - Fatal编程技术网

Domain driven design 使用存储库模式保存复杂聚合

Domain driven design 使用存储库模式保存复杂聚合,domain-driven-design,repository-pattern,Domain Driven Design,Repository Pattern,我们有一个复杂的聚合(出于保密原因而混淆敏感名称) 根R由Ms、As、Cs和Ss的集合组成。Ms拥有其他低级细节的集合。等等 R实际上是一个集合(不公平地建议我们拆分它!) 我们使用延迟加载来检索细节。没问题 但我们正在为如何拯救如此复杂的总量而挣扎 从呼叫方的角度来看: r = repository.find(id); r.Ps.add(factory.createP()); r.Cs[5].updateX(123); r.Ms.removeAt(5); repository.save(r);

我们有一个复杂的聚合(出于保密原因而混淆敏感名称)

根R由Ms、As、Cs和Ss的集合组成。Ms拥有其他低级细节的集合。等等

R实际上是一个集合(不公平地建议我们拆分它!)

我们使用延迟加载来检索细节。没问题

但我们正在为如何拯救如此复杂的总量而挣扎

从呼叫方的角度来看:

r = repository.find(id);
r.Ps.add(factory.createP());
r.Cs[5].updateX(123);
r.Ms.removeAt(5);
repository.save(r);
我们的竞争解决方案是:

  • 脏旗 聚合中的聚合中的每个实体都有一个脏标志。存储库中的save()方法遍历树,查找脏对象并保存它们。删除和添加有点棘手——特别是在延迟加载的情况下——但是可行的

  • 事件侦听器累积更改。 存储库为侦听器订阅更改并累积事件。调用save时,存储库将获取所有更改事件并将它们写入数据库

  • 放弃存储库模式。 实现重载保存方法以单独保存聚合的各个部分。最初的例子是:

    r=repository.find(id); r、 Ps.add(factory.createP()); r、 Cs[5].updateX(123); r、 removeAt女士(5); repository.save(r.Ps); 保存(r.Cs); repository.save(r.Ms)

  • (或更糟)


    请给我忠告!我们该怎么办呢?

    所以,如果你不想使用ORM,你必须构建自己的ORM。您可以将其命名为repository,但实际上这将是一个ORM

    解决方案3反对使用存储库,因此我建议不要使用它。如何在从数据库加载时保存聚合的工作单元状态,然后在提交期间将其与当前状态进行比较?您可以以在内存中存储一些额外数据为代价来摆脱所有脏标记内容。

    解决方案1(使用脏标记)不合适,因为您的持久性逻辑最终会泄漏到域模型中。您的域模型不应该关心持久性:更改了什么,添加了什么,等等

    在Jimmy Nillson的书中,我注意到他处理这个场景的方式是,每次要持久化聚合时,都会更新聚合根,删除其所有子级,然后再次插入每个子级

    这是一个相当容易实现的解决方案,但是它有一些含义。例如,每次重新插入子对象时,其ID可能会更改。如果另一个用户同时编辑同一聚合怎么办

    以前有没有其他人遇到过这个问题


    MOSH

    我认为你没有使用现成的ORM,这通常会为你处理这个问题。因为子实体不应该有全局标识,所以子对象ID可以改变的事实不应该是一个问题。请考虑这个例子:用户可能想删除属于订单1的OrthItIt 11。这可以通过像GetOrder(1.RemoveItem(11)这样的方法实现。同时,另一用户可能正在更新订单1。因此,重新插入Order 1及其所有子项可能会导致OrderItems的ID发生更改。因此,在这种情况下,OrderItem11可能会变成OrderItem15。因此,对GetOrder(1).RemoveItem(11)的调用将失败。我有什么遗漏吗?请澄清。