15

I have two entities Publisher and SocialAccount. SocialAccount contains multiple accounts like Twitter, Facebook, etc.

1 publisher can attach to many social accounts and 1 social account contains multiple publishers, this social account is also connected with another entity's campaign. I mean both are an independent entities

When creating a publisher instance it is not necessary that it should subscribe to a social account, it can subscribe to it at a later stage.

I need to subscribe publisher to 1 or multiple social accounts. how do I do that

How can I convert m to m relationship into 1 to many relationship, between publisher and social account? I am not sure because I read in many places that we should avoid M to M relationship between entities.

Reza Heidari
  • 1,192
  • 2
  • 18
  • 23
chandra
  • 313
  • 1
  • 3
  • 8
  • Is your question about coding the entities themselves, or about how to e persist the entities to a database? If you're just talking about the entities, then just change the SocialAccount from having a collection of Publishers to having a reference to a single Publisher. – David Dec 06 '10 at 12:02
  • i am confuse on both. Publisher is not aggregate root of Social Account. How will i persist then. – chandra Dec 06 '10 at 13:24
  • I need to know how in DDD, relationships are handled. Both one to many and many to many, In same aggregates and in different aggregates. There is no such information in internet. I googled alot – chandra Dec 06 '10 at 13:26

1 Answers1

13

Let me expand on Don's answer, as I think he is leading you on the right track.

M-to-N relationships are natural, useful, and can be handled in DDD. If you require an M-to-N relationship, you don't need to try and convert it to an (or more likely multiple) M-to-1 relationship(s). Udi Dahan's acticle gives a nice example of how to handle an M-to-N relationship between entities.

First, determine which entity should contain a list of IDs of the other. Udi uses the example of job postings (Job) and job posting boards (JobBoard). Since a job can exist without a job board and a job board cannot exist without jobs, JobBoard is chosen as the aggregate root and will contain a List<Job>. This might seem like an M-to-1 relationship, but, as each Job can be in the list for multiple JobBoards, it is really M-to-N.

In your case of SocialAccount and Publisher, I recommend something like this in C#:

public class Publisher
{
    public int ID {get; private set;}
    
    private readonly IList<int> _AssignedSocialAccounts = new List<int>();
    public IEnumerable<int> AssignedSocialAccounts { get { return this._AssignedSocialAccounts; } }
    
    public Publisher(int ID) //Pass required fields to the constructor.
    {
        this.ID = ID;
    }
    
    public AssignSocialAccount(int SocialAccountID)
    {
        if(!this._AssignedSocialAccounts.Contains(SocialAccountID))
            this._AssignedSocialAccounts.Add(SocialAccountID);
    }
}

public class SocialAccount
{
    public int ID {get; private set;}
    
    public SocialAccount(int ID) //Pass required fields to the constructor.
    {
        this.ID = ID;
    }
}

(This example uses domain encapsulation similar to Jimmy Bogard's Wicked Domain Models.)

Note that I chose Publisher to be the aggregate root since a SocialAccount can exist on its own, but a Publisher has no meaning without the existence of a SocialAccount.

Also note that I am passing around unique IDs, not references to the objects themselves. This is a common approach in DDD and allows for the lazy loading of related entities, although the tradeoff is you have to call the repository to get the entities when you want to access them.

This approach also means that you do not have all SocialAccounts as a single enumeration. They are split up between the various Publishers. To get a list of all SocialAccounts will require a separate query.

whyer
  • 783
  • 5
  • 16
Justin J Stark
  • 490
  • 1
  • 8
  • 17
  • 9
    I'd say that both `SocialAccount` and `Publisher` are aggregate roots with their own independent lifecycles. – Eugene Khudoy Jan 18 '18 at 15:47
  • 1
    @EugeneKhudoy They certainly can be. The general rule is to keep your aggregates small but it really depends on your application. [Rule: Design Small Aggregates, Implementing Domain-Driven Design, Vaughn Vernon](http://www.informit.com/articles/article.aspx?p=2020371&seqNum=3). – Justin J Stark Jan 18 '18 at 22:22
  • Don't understand why a JobBoard wouldn't make sense on its own - not sure what's wrong with an empty board as the concept of a board that can store job postings is still valid when there are no job postings posted on the board. Same thing with Publisher and SocialAccounts. Wouldn't it be more appropriate to have a membership class where you can bind a job to a board (or a publisher to a social account) – Kappacake Apr 01 '22 at 12:48
  • After reading Udi's article, I seem to understand that the reason why you can use a m-1 between job and job board is that the main application users will use won't need to get boards from jobs. Therefore, even if administrative applications might need that, is preferred to favor the main application with a simpler model at the cost of having a query, which is "not as pretty as object traversal" to cite Udi's article. Hope this helps someone who, like me, is confused about this :) – Kappacake Apr 01 '22 at 15:39