8
votes

I am struggling to identify Domain objects.

Problem:

  • A company has one or multiple Sites
  • A Site has main and multiple contacts
  • Thus, a company has one or many contacts. These contacts are allocated to Sites.
  • Contacts must be added to Sites not to a company

My Understanding:

public class Company : IEntity
    {
         public int CompanyId {get;}
         public string CompanyName {get;}
         //.....
    }

    public class Site : IEntity
    {
         public int SiteId {get;}
         public string SiteName {get;}
         //.....
    }

    public class Contact : IEntity
    {
        public int ContactId {get;}
        public string SurName {get;}
        public bool MainSiteContact {get;}//Confused!! May be this is not the right place
         //.....
    }

    public class SiteContact : IAggregate
    {
        public Site ASite { get; }
        public List<Contact> Contacts { get; }
        public Contact MainContact {get;}//Confused!! 
        //.....
        public Contact AddSiteContact(...)
        {
        }
    }

    public class CompanySites : IAggregateRoot
    {
        public Company ACompany { get; }
        public List<Site> Sites { get; }
        public List<SiteContact> Contacts { get; }
        //.....
    }

Am i in the right direction? Please correct me if i am wrong...

Update @Beachwalker elaborate the question properly in the comment section below the answer of @Aydin Adn.

@Aydin Adn I think his questions has more than one aspects: 1. How these objects fit correctly in the context of a Domain Driven Design (DDD) aproach and what is their DDD presentation, e.g. AggregateRoot, Entity, ValueObject etc. 2. Is the interpretation of the Domain correct. (Domain Model)

1
Just type it in as you explain. You create a link table CompanySites which is a many-to-many relationship, but the way you explain it, Site just needs a CompanyId and Company needs a set of Site.Silvermind
@Silvermind so do you reckon that there are no need of CompanySites or aggregate root? Just need to add Company ID in site class.MJK
Yes, @AydinAdn has an example that exactly reflects your explanation.Silvermind

1 Answers

16
votes

First: https://www.infoq.com/minibooks/domain-driven-design-quickly - read What Is DDD and The Ubiquitous Language chapters 3 times.

The answer to how your entities are modeled is based in the understanding of the business system for which you are developing the software. This is one of the important parts of DDD - modelling comes after understanding, it is Domain Driven Design not Database Driven Design.

You have described your problem in terms of traditional data modeling, which is fine and good but is not really DDD. You need to describe the problem in business or operational terms.

Without additional domain knowledge we cant help in identifying an effective model. However, as an exercise I'm going to alter the problem description to focus more on a business perspective:

  1. Our company provides site management services
  2. Companies register sites for us to manage
  3. Registered sites must have at least one point of contact with the authority to allow our company to perform our services on site.
  4. Registered sites will have one point of contact that is the preferred contact. This contact will be contacted first when our company needs to interact with a registered site.

The above matches your original 'Problem', but now it is presented in such a way the it aligns with (my made up version of) how the business sees it. There is context and reasoning to each of the points which is critical for the modelling process. From this we can pick out some nouns that indicate entities: Company, Site, Contact. It also suggests an aggregate root: Site

class Site : IEntity, IAggregate {
  public SiteKey Key {get}

  public CompanyKey CompanyKey {get}
  public ContactKey PrimaryContactKey {get}
  public IEnumerable<ContactKey> ContactKeys {get}

  public string SiteName {get}

  // domain logic here
  // ...
}

Now the cool thing about DDD is that we now have more questions to ask: How are contacts changed? Can a site be moved to a new company? What properties of a site are needed for us to managed them? How are new sites registered - what is the minimum properties required? The answers to these questions will result in a far superior business business application than a simple collection of CRUD technically correct collection of screens and rules that are a pain in the bum for the end users to deal with.

Now it is extremely import to state here that this is the DOMAIN model - not the final database model (which will end up looking pretty much how you have described). The biggest gotcha for DDD is to bring a CRUD based mindset which implies that the program classes must match the database tables: Be prepared for your domain Model not to match your database model. Also, be prepared to provide mechanisms for getting 'dumb' lists from your data stores as required and don't be afraid of mixing CRUD operations for entities/collections with no real business value.

Keep an open mind - DDD is a great pattern and a gateway to many insights into software development.