我们有一个复杂的聚合(敏感名称因保密原因而被混淆)。
根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.Ms.removeAt(5); repository.save(r.Ps); repository.save(r.Cs); repository.save(r.Ms);
(或更糟)
请咨询!我们该怎么办?
答案 0 :(得分:2)
解决方案1(使用脏标志)不合适,因为最终您的持久性逻辑泄漏到域模型中。您的域模型不应该关心持久性:更改内容,添加内容等等。
在Jimmy Nillson的书中,我注意到他处理这种情况的方式是,每次聚合都要保留,聚合根被更新,所有子代都被删除,然后再插入每个。
这是一个相当容易实现的解决方案,但它有一些含义。例如,每次重新插入子对象时,其ID都可能会更改。如果其他用户同时编辑同一聚合怎么办?
之前是否有其他人遇到此问题?
MOSH
答案 1 :(得分:0)
所以,如果你不想使用ORM,你必须建立自己的ORM。您可以将其命名为存储库,但实际上这将是一个ORM。
解决方案3违反了存储库的想法,所以我建议不要使用它。如何在从数据库加载的时刻保存聚合的工作单元状态以及稍后在提交期间将其与当前状态进行比较?您可以以存储内存中的一些额外数据为代价来摆脱所有脏标记。