【问题标题】:Domain Driven Design - Aggregate for transactional consistency领域驱动设计 - 聚合以实现事务一致性
【发布时间】:2013-06-07 18:29:57
【问题描述】:

我正在开发一个 CMS 类型的应用程序,并希望使用一些 ddd 战术模式。情况如下:

应用程序处理项目的创作和发布。

项目在工作流组中组合在一起。在该组中,一项可能被标记为“已发布”,一项被标记为“工作中”,任何数字都被标记为“已归档”。

只有在“工作”状态下才能编辑项目。

发布工作项目时,它会替换其相应的已发布项目(如果有),然后将其标记为已存档。

如果不存在草稿,则可以通过复制已发布的版本或任何存档版本来创建新的工作版本。

问题是,按照聚合应封装系统不变量的指导,工作流组是否应该是聚合根 - 包含其所有项?

我担心这会产生相当大的聚合,并且会阻止项目在全球范围内可访问(即所有交互都必须通过 Workflow Group AR)。

我看到的另一种方法是使 Item 成为 Aggregate Root,然后让 Domain Service 处理事务和不变量。例如:

PublishWorkingItem(int itemId) 
{
    Item workingItem = itemRepo.GetWorkingItem(itemId);
    Guid groupId = workingItem.GroupId;
    Item publishedItem = itemRepo.GetPublishedItemForGroup(groupId);
    if(publishedItem != null) 
    {
        publisheditem.Archive();
    }
    workingItem.Publish();  
}

【问题讨论】:

    标签: transactions domain-driven-design aggregation domainservices aggregateroot


    【解决方案1】:

    如果您还没有阅读过,我强烈建议您阅读 vaughn vernon 关于effective aggregate design 的系列文章。 第 II 部分建议您咨询您的领域专家,了解系统中是否可以接受陈旧数据。如果答案是肯定的,您可以考虑使用保持最终一致性而不是事务性的小型聚合(例如您的域中的项目)。例如,这可能意味着在一小段时间内,可能有两个项目处于已发布状态,但最终只会发布一个项目。您可以使用 域事件 实现这种行为。拥有一个由事务组成的大型聚合也是一种选择,但如果许多用户试图同时操作同一个组,它可能会导致高并发争用。

    【讨论】:

      【解决方案2】:

      AR 应该有自己的生命周期。这是您应该能够从您的领域专家那里得到的东西。

      AR 还在于在高度内聚的对象图周围具有锐利的边缘。

      如果您发现另一个 AR 包含在另一个 AR 中,则需要删除包含的 AR,并将其替换为仅包含的 ID 或值对象。

      在您的情况下,活动项目和已归档项目之间可能存在差异,因此已归档项目不属于 Workflow AR。但您最终可能会将 Item 设为 AR,在这种情况下,您的 Workflow AR 可能包含活动项目 ID/VO 的列表。

      只是一些想法:)

      【讨论】:

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