2017-09-14 2 views
1

Je travaille sur une application de support technique utilisant DDD. Ma question est de savoir comment gérer au mieux une entité qui pourrait faire référence à deux RA possibles. J'ai une RequestSubscriber qui est abonnée à demander des mises à jour. Cet abonné est un Agent ou un Contact.DDD: Comment gérer plusieurs liaisons racines agrégées possibles

La question est-est-ce que je devrais avoir une référence facultative à l'agent ou au contact et remplir seulement un ou avoir une référence de personne générique avec un type associé pour s'assurer que le lien arrive au bon endroit?

Options Modèle:

// 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; } 
} 

contructeurs:

// 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); 
    } 
+0

Une pensée supplémentaire est peut-être que je devrais vraiment avoir deux abonnés différents - abonné d'agent et abonné de contact. –

+0

La classe 'Subscriber' que vous avez mentionnée me manque. Pourquoi et comment le 'RequestSubscriber' est-il important de savoir quel est le' IPerson'? Quelle est la limite d'invariant/cohérence protégée par ce RA? –

+0

Mes excuses, le 'RequestSubscriber' est le nom de la classe d'abonné. C'est important parce que les notifications par email pour un 'Contact' seront différentes de' Agent'. –

Répondre

0

Une option peut être d'ajouter un autre niveau d'indirection :)

Votre RequestSubscriber semble réunir un Request et un Subscriber . Vous passez dans un Request mais il peut y avoir un concept manquant dans la partie Subscriber.

De même qu'un Request résume quelle que soit la requête, votre Subscriber peut résumer ce que votre abonné représente.

S'il y a une autre raison pour laquelle vous avez besoin du SubscriberType alors peut-être que cela peut changer l'implémentation.

+0

J'ai pensé à cela et à l'OMI qui ne ferait que passer le problème de 'RequestSubscriber' à' Subscriber'. –

+0

Ah, j'ai relu votre commentaire et vous l'avez mentionné. Cela dépendra du problème réel que l'on va résoudre. –