0

I have two domain objects, a Parent and Child. A Parent can have zero or more children, and a Child can belong to zero or more parents (in case of divorced parents).

So thinking about this in the context of Domain Driven Design I'd say that both Parent and Child are an AggregateRoot. Because this is a many-to-many relationship.

Now I'm wondering how I should model this in code. I need to be able to access the parents from the Child class, but also all the children from the Parent class.

So I'm thinking about doing it like this:

public class Parent : AggregateRoot
{
    public string FamilyName {get;set;}
    public IList<Guid> ChildrenIds {get;set;}
}

public class Child : AggregateRoot
{
    public string Name {get;set;}
    public IList<Guid> ParentIds {get;set;}
}

Is it OK to have both classes reference each other via their id's?

Or is there perhaps a better way to model this?


Background info

Parents and their children can be registered in our application. Our system then keeps a log of events that that child goes through. Swimming, going to the museum etc.

For example;

  • a mom and her only child are registered in our application.
  • In the mean time events are logged to the child entity. Visited a museum, went swimming etc.
  • Two months later Dad needs to be registered in our system as well (coparenting). Mom and Das obviously should have a reference to the same child entity.

I need to be able to work with the following use case:

  • On all even weeks of the year Mom is responsible for the child.
  • On all uneven weeks Dad is responsible.
  • If something happends on an even week (Mom), then this event will be registered.
  • If the application later on retrieves the Dad aggregate, then he should not only get a reference of the same child as Mom, but should also see all the events that happend the week before.

So therefor a Parent can have many Children, and a Child can hsve many Parents. My problem is that I'm not sure how to model this in DDD.

Vivendi
  • 20,047
  • 25
  • 121
  • 196
  • Based on your description, I'm not sure that either `Parent` or `Child` should be an AggregateRoot. Have you considered abstracting both within another Aggregate (e.g. `Family`)? What are the commands that are processed by Parents and Children? – Aaron M. Eshbach Feb 26 '18 at 21:34
  • @AaronM.Eshbach I could create an Aggregate `Family`. Does that mean that both `Parent` and `Child` are not aggregates anymore when they fall within the `Family` Aggregate? Also I still need the flexibility to add the same `Child` to another `Parent`, which would then be from another `Family`. How should I model that? – Vivendi Feb 26 '18 at 21:51
  • 1
    If you create a `Family` aggregate, then Parent and Child would both be entities that belong to that aggregate. As a general rule a type of entity can only belong to one Aggregate, but I don't see a problem with having the same instance of an entity have an association with two other entities of the same type. – Aaron M. Eshbach Feb 26 '18 at 22:08
  • Maybe I left out something important. I have a `Family` Aggregate. That has a `Parent` entity (Mom). Mom has one `Child` with some properties. Mom and are Dad are divorced. So Dad lives in another`Family`, thus is the `Parent` of that family. Dad also has one `Child`. This must be the same child as Moms. When the Mom Aggregate updates a property of her Child, then this should also be reflected to Dads `Child` entity. (Because we're talking about the same child). I don't see how this is possible in your example without giving `Child` its own AggregateID? Could you maybe elaborate on your idea? – Vivendi Feb 26 '18 at 22:22
  • You should definitely reference other Aggregate Roots by id. Please refer to http://www.informit.com/articles/article.aspx?p=2020371&seqNum=4. – Zeljko Vujaklija Feb 27 '18 at 12:46
  • After reviewing your background info, it sounds like `Child` actually needs to the AggregateRoot, and that the `Parent` and `Family` are just entities associated with the `Child`. Are there domain events that apply to the `Parent` or the `Family` independently of the `Child`? – Aaron M. Eshbach Feb 27 '18 at 13:36
  • @Vivendi DDD aggregates are here to transition your system to its following state while enforcing *invariants* and business rules. From your problem description, there doesn't seem to be any. Aren't you overthinking a part of your model that is really secondary? What are the crucial rules that would break your application if not enforced? – guillaume31 Feb 28 '18 at 10:48

1 Answers1

0

When ever I have two models that reference each other I force myself to look for a missing part of my puzzle.

It sounds like your business doesn't care who is the parent of a child is, it cares who is responsible for a child at a given point in time. So its possible that looks like you are missing a 3rd domain model: Guardian (Im sure their is a better name for this) which removes the need for Parent and Child entities to explicitly reference each other.

class Guardian {
    GuardianId Id {get;private set;}
    ParentId ParentId {get;private set;}
    ChildId ChildId {get;private set;}
    List<DateRule> WhenResponsible {get;private set;}

    bool IsResponsibleForChildAt(date day) {
      return WhenResponisble.Any(dr=>dr.AppliesToDate(day));
    }
}

Now depending on your business the Guardian model may more naturally fit inside the Child or Parent models, your domain experts should be able to help here.

Joe
  • 1,327
  • 1
  • 10
  • 19