DDD – Making meaningful relationships

A recent discussion on the DDD forum made me want to post about what I consider to be an under-appreciated aspect of domain modelling, namely relationships. In the thread Randy Stafford said the following:

Note that RoleRegistration is an example of a Relationship Object – arguably a fourth archetype of domain object alongside Entity, Value Object, and Aggregate.

I couldn’t agree more with this, in a domain model I worked on recently we had a stack of very useful and very meaningful relationship objects that served a range of purposes.

For example if a Client has Accounts then it is possible that you can get away with just having that as a direct relationship but its equally possible that the relationship itself is meaningful and carries its own data/behavior. In this case you might have a type association with the relationship that would explain if the Client owns the Account, or whethery just manage it, or whether they are actually just one of several owners.

Aggregates

You need to consider aggregate boundaries especially carefully when using Relationship Objects.

In the case of an association between a Client and an Account the relationship probably belongs to the Client aggregate.

Then again if you choose to model the association between a Client and SalesAdvisor using a full blown party/role/relationship approach then things become a big more complex. Are all parties and roles and relationships different aggregates or does a relationship own the two roles it composes?

If its the latter then you may be breaking an aggregate design rule because the party now refers to a piece of the relationship aggregate other than root.

Temporal Associations

Another common case is that the relationship is temporal which brings with it a lot of complexity and should only be done with extreme care.  If your sure you need temporal associations then you will find Martin Fowlers patterns invaluable.

Encapsulating Relationships

Most of the relationships have real meaning in their own right but sometimes they are just an artifact of the design, in those cases you can demote the associations to being just an encapsulated detail.

Take the association between Client and Account, maybe when you ask for the Accounts for a Client you want to get the Account objects rather than the ClientAccountRelationship objects.

If this were the case you could keep the ClientAccountRelationship class, which has its own data/behaviour and makes mapping easier, but entirely hide it from users of the domain. One way to do this is to create custom collection called ClientAccounts and have it wrap and IList of ClientAccountRelationships whilst acting like it is just a simple IList of Accounts, it can also provide helpful methods like FindPrimaryOwner.

Summary

I mention all of this because when I got started with DDD relationship objects bothered me especially as we were working with a legacy database and I saw the relationship objects as being a problem caused by the number of join tables. At the time my plan was to get rid of a lot of them by taking advantage of NHibernate magic.

However as I got a bit more experience I realized that they were key and although we encapsulated some (when they were just an artifact of the design) we made others totally key parts of the design. In both cases the relationships themselves were very useful.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

This entry was posted in DDD. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

One Response to DDD – Making meaningful relationships

  1. Nuno Lopes says:

    “In the case of an association between a Client and an Account the relationship probably belongs to the Client aggregate.”

    Most probably it belongs to the account :)

    Client – Account

    You have to ask yourself which is more specific. Is it the account or the client?

    If you have a one to one relationship between both, most probably both concepts would be collapased into one (Either client or Account). The Domain Expert would tell what is the most meaningfull name.

    Now if the Client may open several accounts then it is another matter.

    For instance a bank account. When a loan is approved you the client states which account will be used to make payments.

    So you have:

    Client-Loan-Account
    Client-Loan-Payment-Account

    If you state that the relationship belongs to the Client (composition pattern). Then by definition all operations related to the account would be put in the Clien class. You would be in a BIG MESS.

    Usually the most specific carries the buiness load.

    Unless your concept of belongs is meaningless.

    Read Streamlined Object Modeling.

    Have fun,

    Nuno

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>