Domain driven design DDD:如何处理多个可能的聚合根链接

Domain driven design DDD:如何处理多个可能的聚合根链接,domain-driven-design,aggregate,Domain Driven Design,Aggregate,我正在使用DDD开发一个帮助台应用程序。我的问题是如何最好地处理可以引用两个可能的AR的实体 我有一个RequestSubscriber,是一个订阅请求更新的人 此订户是代理或联系人 问题是,我应该有一个对代理或联系人的可选引用,并且只填写一个,还是应该有一个带有关联类型的泛型person引用,以确保链接到达正确的位置 型号选项: // This public class RequestSubscriber : DomainEntity, IPerson { // Constuctors

我正在使用DDD开发一个帮助台应用程序。我的问题是如何最好地处理可以引用两个可能的AR的实体

我有一个
RequestSubscriber
,是一个订阅请求更新的人

此订户是
代理
联系人

问题是,我应该有一个对代理或联系人的可选引用,并且只填写一个,还是应该有一个带有关联类型的泛型person引用,以确保链接到达正确的位置

型号选项:

// This
public class RequestSubscriber : DomainEntity, IPerson
{
    // Constuctors...

    public Guid? Agent_Id { get; private set; }
    public Guid? Contact_Id { get; private set; }
    public SubscriberType Type { get; private set; }
    public Email Email { get; private set; }
    public PersonName Name { get; private set; }
}

// Or This
public class RequestSubscriber : DomainEntity, IPerson
{
    // Constuctors...

    public Guid Person_Id { get; private set; }
    public SubscriberType Type { get; private set; }
    public Email Email { get; private set; }
    public PersonName Name { get; private set; }
}
承包商:

    // This
    public RequestSubscriber(Guid id, Request request, IPerson person) : base(id)
    {
        Guard.ForNull(request, nameof(request));
        Guard.ForNull(person, nameof(person));

        if(person is Agent agent)
        {
            Email = agent.Email;
            Name = agent.Name;
            Type = SubscriberType.Agent;
        }
        else if (person is Contact contact)
        {
            Email = contact.Email;
            Name = contact.Name;
            Type = SubscriberType.Contact;
        }
        else
        {
            throw new ArgumentException("Subscribers must be an agent or contact", nameof(person));
        }

        request.Subscribe(this);
    }

    // Or This
    public RequestSubscriber(Guid id, Request request, Agent agent) : base(id)
    {
        Guard.ForNull(request, nameof(request));
        Guard.ForNull(agent, nameof(agent));

        Email = agent.Email;
        Name = agent.Name;
        Type = SubscriberType.Agent;

        request.Subscribe(this);
    }

    public RequestSubscriber(Guid id, Request request, Contact contact) : base(id)
    {
        Guard.ForNull(request, nameof(request));
        Guard.ForNull(contact, nameof(contact));

        Email = contact.Email;
        Name = contact.Name;
        Type = SubscriberType.Contact;

        request.Subscribe(this);
    }

可以选择添加另一个间接级别:)

您的
RequestSubscriber
似乎将
请求
订户
组合在一起。您正在传递一个
请求
,但是
订户
部分可能缺少一个概念

同样的,一个
请求
抽象出你的
订阅者的任何请求
可以抽象出你的订阅者代表的任何东西


如果您需要订阅类型的另一个原因,那么它可能会更改实现。

一个选项可能是添加另一个间接级别:)

您的
RequestSubscriber
似乎将
请求
订户
组合在一起。您正在传递一个
请求
,但是
订户
部分可能缺少一个概念

同样的,一个
请求
抽象出你的
订阅者的任何请求
可以抽象出你的订阅者代表的任何东西


如果您需要
SubscriberType
还有另一个原因,那么它可能会改变实现。

另外一个想法是,也许我真的应该有两个不同的订阅者代理订阅者和联系订阅者。我错过了您提到的
subscriber
类。这对
请求订阅者
什么样的
IPerson
有什么关系?AR保护的不变/一致性边界是什么?很抱歉,
RequestSubscriber
是订阅者类名。这主要是因为
联系人
的电子邮件通知不同于
代理
。在这种情况下,我将使用第二种方法(类型标志)。另外一个想法是,我可能真的应该有两个不同的订阅者代理订阅者和联系人订阅者。我错过了您提到的
订阅者
类。这对
请求订阅者
什么样的
IPerson
有什么关系?AR保护的不变/一致性边界是什么?很抱歉,
RequestSubscriber
是订阅者类名。这主要是因为
联系人
的电子邮件通知不同于
代理
。在这种情况下,我会使用第二种方法(类型标志)。我考虑过这一点,IMO只会将问题从
请求订户
代理到
订户
。啊,我重新阅读了你的评论,你确实提到了这一点。这将取决于实际问题是什么,一个人将要移动。我考虑过这一点,我认为这只是将问题从
RequestSubscriber
代理到
Subscriber
。啊,我重新阅读了你的评论,你确实提到了这一点。这将取决于实际问题是什么,一个人将要移动。