分布式领域驱动设计建模

问题描述 投票:0回答:2

我正在开发一个活动票务系统,我正在尝试使用 DDD。但是,我不确定如何对我的一些聚合进行建模。

我有主要活动汇总:

public class Event : Entity<Guid>, IAggregateRoot
{
    public string Name { get; private set; }
    public Organizer Organizer { get; private set; }
    public Venue Venue { get; private set; }
    public DateTime StartsAt { get; private set; }
    public short MinAge { get; private set; }
    public bool IsAvailable { get; private set; }
    public EventType Type { get; private set; }
    //constructor and mehtods
}

还有场地和组织者汇总:

public class Venue : Entity<Guid>, IAggregateRoot
    {
        public string Street { get; }
        public Venue(Guid id, string street) : base(id)
        {
            Street = street;
        }
    }


    public class Organizer : Entity<Guid>, IAggregateRoot
    {
        public Organizer(Guid id) : base(id)
        {
        }
    }

我的问题是:

  • 我有不同的服务来处理场地和组织者的创作和其他操作。活动服务正在使用来自其他两个服务的 kafka 消息,并将场地和组织者保存在自己的数据库中。我想提一下,场地和组织者服务比活动服务拥有更多有关其各自实体的信息,因此它不是 100% 的数据重复。这是在不同服务之间共享数据的正确方法吗?

  • 在活动服务中,组织者和场地应该被视为一个集合体还是一个实体?这些都不能在事件服务的上下文中单独访问。

  • 我应该如何处理从数据库中持久化和检索实体?

c# domain-driven-design dddd
2个回答
1
投票

实体是具有自己的实体、唯一标识符且具有重要性的事物。 当您拥有具有强依赖性的实体(以及值对象)并且有必要像管理单个对象一样管理所有实体时,您可以使用聚合。在这种形式中,您在外部与管理所有聚合实体的某个实体(聚合根)一起工作。

用例子更容易理解。假设您有 Invoice 实体和 InvoiceLine 实体。它们都很重要,具有唯一的标识符......并且您可以将它们作为实体来使用。数据库中有一个用于发票和行的表。按原样使用实体,您必须控制一些事情,例如发票总额。当您在任何地方更改某行的价格时,您需要靠近发票才能更新总计。这是一个非常简单的例子,但在更复杂的场景中,这种事情会以错误的数据结束,因为在某些地方,你忘记更新一些相关的数据。

因此,有趣的是,有一个包含这两个聚合的聚合根,并且它们的所有内容都封装在根聚合中。您可以通过聚合根更新行价格,并通过根更新发票总额。每个实体都有一个对根的引用。

通常,聚合根有一个存储库来管理其所有聚合的数据。实体框架在这一点上略有不同,每个实体都有一个存储库。


0
投票

虽然有点晚了,但值得一说。

这是在不同服务之间共享数据的正确方法吗?

我认为共享数据的方式在这里不会成为问题。他们通过消息代理共享和更新数据,这一切都很好。更好的问题是为什么首先要分离这些有界上下文?创建有界上下文的成本很高。所以你创建 BC 背后必须有充分的理由。

组织者和场地应被视为集合体还是集合体? 实体?

我认为他们应该拥有自己的总量。因为

Event
不管理有关它们的任何内容(所有不变量都是在其原始有界上下文中定义的)。它们只是原始数据的副本。

我应该如何处理持久化和检索实体 数据库?

我不太明白你的意思,但我认为集成事件是修改克隆数据的触发器。因此,在集成事件处理程序中,您应该从其存储库获取相应的地点/组织者并将更改应用于它们。

© www.soinside.com 2019 - 2024. All rights reserved.