DDD:在另一个AR中创建一个聚合根 [英] DDD: Create one aggregate root within another AR

查看:153
本文介绍了DDD:在另一个AR中创建一个聚合根的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的域中有2个聚合根(AR),并且在1号调用某种方法需要访问2号实例。 在DDD中,如何以及在哪里进行第二AR的创建和创建?

Suppose that I have 2 aggregate roots (AR) in my domain and invoking some method on the 1st requires access to an instance of the 2nd. In DDD how and where should retrieval and creation of the 2nd AR happen?

以下是一个人为设计的示例 TravelerEntity code>需要访问 SuitcaseEntity 。我正在寻找不会用基础结构代码污染域层的答案。

Here's a contrived example TravelerEntity that needs access to a SuitcaseEntity. I'm looking for an answer that doesn't pollute the domain layer with infrastructure code.

public class TravelerEntity {
    // null if traveler has no suitcase yet.
    private String suitcaseId = ...;
    ...

    // Returns an empty suitcase ready for packing. Caller 
    public SuitcaseEntity startTrip(SuitcaseRepository repo) {
        SuitcaseEntity suitcase;
        if (suitcaseId == null) {
          suitcase = new SuitcaseFactory().create();
          suitcase = repo.save(suitcase);
          suitcaseId = suitcase.getId();
        } else {
          suitcase = repo.findOne(suitcaseId);
        }

        suitcase.emptyContents();

        return suitcase;
    }
}

处理启动行程请求的应用程序层服务将得到通过DI适当的 SuitcaseRepository 实现,通过 TravelerRepository TravelerEntity c>实现并调用其 startTrip()方法。

An application layer service handling the start trip request would get the appropriate SuitcaseRepository implementation via DI, get the TravelerEntity via a TravelerRepository implementation and call its startTrip() method.

我想到的唯一选择是移动 SuitcaseEntity 管理到域服务,但是我不想在旅行之前创建手提箱,也不想以贫乏的 TravelerEntity

The only alternative I thought of was to move SuitcaseEntity management to a domain service, but I don't want to create the suitcase before starting the trip, and I don't want to end up with an anemic TravelerEntity.

我对一个AR创建并保存另一个AR有点不确定。因为仓库和工厂封装了有关第二个AR的详细信息,这样可以吗?我有想念的危险吗?还有更好的选择吗?

我很新,可以DDD质疑我对此的想法。我发现的关于AR的其他问题似乎集中在正确识别它们,而不是管理彼此之间的生命周期。

I'm new enough to DDD to question my thinking on this. And the other questions I found about ARs seem to focus on identifying them properly, not on managing their lifecycles in relation to one another.

推荐答案

理想情况下, TravelerEntity 不会操纵 SuitcaseRepository ,因为它不应该知道存放手提箱的外部物品,仅涉及其自身内部。相反,它可以新建一个 SuitCase 并将其添加到内部的[手提箱]列表中。如果您希望在不专门将手提箱添加到存储库的情况下使用ORM,则必须将整个手提箱对象存储在 TravelerEntity.suitcaseList 中,而不仅仅是ID ,这与存储对其他AR作为ID的引用的最佳做法相冲突。

Ideally TravelerEntity wouldn't manipulate a SuitcaseRepository because it shouldn't know about an external thing where suitcases are stored, only about its own internals. Instead, it could new up a SuitCase and add it to its internal [list of] suitcases. If you wanted that to work with ORMs without specifically adding the suitcase to the repository though, you'd have to store the whole suitcase object in TravelerEntity.suitcaseList and not just its ID, which conflicts with the "store references to other AR's as IDs" best practice.

此外, TravelerEntity.startTrip()放回手提箱似乎有些人为和不明确,如果您需要归还由 startTrip()创建的其他实体,将会遇到麻烦。因此,一个好的解决方案是,一旦 TravelerEntity 添加了行李箱数据,便发出带有手提箱数据的 SuitcaseAdded 事件。手提箱到它的清单。应用程序服务可以订阅事件,将手提箱添加到 SuitcaseRepository 并提交事务,从而有效地将新手提箱和修改过的旅行者保存到数据库中。

Moreover, TravelerEntity.startTrip() returning a suitcase seems a bit artificial and unexplicit and you'll be in trouble if you need to return other entities created by startTrip(). So a good solution could be to have TravelerEntity emit a SuitcaseAdded event with the suitcase data in it once it has added the suitcase to its list. An application service could subscribe to the event, add the suitcase to SuitcaseRepository and commit the transaction, effectively saving both the new suitcase and the modified traveler to the database.

或者,您可以将 startTrip()放在域服务而​​不是实体中。使用 SuitcaseRepository 可能更合法,因为允许域服务知道多个域实体和整个域过程。

Alternatively, you could place startTrip() in a Domain Service instead of an Entity. There it might be more legit to use SuitcaseRepository since a domain service is allowed know about multiple domain entities and the overall domain process going on.

这篇关于DDD:在另一个AR中创建一个聚合根的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆