1

I'm having trouble modelling a relationship in DDD. I have four entities:

  • Claim - defines access to a Service.
  • Service - a web service. A Service has many Claims and can belong to any number of Teams.
  • Role - contains a collection of Claims from any number of Services. Roles always belong to a Team.
  • Team - contains a collection of Roles, and Services.

When I remove a Claim from a Service, it should also be removed from all Roles that have that Claim assigned to them. Equally, when I change the name of a Service, that name should be reflected in all the Teams.

I currently have a Service aggregate root (to allow Services to be added and altered independently of any one Team), and a Team aggregate root (to allow management of Team-specific Roles). This creates two problems:

  • Changes in the Service aggregate are not reflected in the Team aggregate
  • When a Claim is removed from a Service, there is no way to cascade this into the Team's roles.

There's something clearly horribly wrong with my model, and was wondering if anyone can illuminate where I've gone awry.

asked Apr 14, 2016 at 14:36
3
  • 1
    This sounds like a description of your attempted solution to model the problem, but without any description about the problem itself. See What is the XY problem? Commented Apr 14, 2016 at 15:11
  • The requirements are specified in condensed form in the first four bullet points. Commented Apr 14, 2016 at 15:46
  • 1
    Note that DDD is not a software development methodology; it is a software design methodology. Nothing in DDD prevents you from actually writing code that performs your required functions. Commented Apr 14, 2016 at 15:55

1 Answer 1

1

Why does a Role have a direct relation to Service, when the relation obviously requires a Claim to exist? Just forget about that one.

Respectively where is there a relation between Service and Team? Add an indirection via an Ownership entity to model that.

Choosing Team and Service as the only root aggregates is correct.

Team 1 <-> * Role
Role 1 <-> * Claim
Service 1 <-> * Claim
Team 1 <-> * Ownership
Service 1 <-> * Ownership

By making the relations traversable in both directions, you can already reach each entity required to access all related information required.

There is no actual need to ever store Service names in a Team, that information can be aggregated by navigating both along the Claim and the Ownership relations.

As a Claim holds both a reference on a Role and on a Service, you must traverse both parents when deleting a Claim. The same goes for Ownership. It doesn't matter which parent owns the child and which just holds a reference, that's just an implementation detail.

answered Apr 14, 2016 at 15:50
2
  • 1
    My understanding was that relationships should have a single traversable direction. Commented Apr 14, 2016 at 16:08
  • 1
    Navigation may be allowed either unidirectional or bi-directional, that doesn't matter. What you mean is probably parent-child relations in languages which differentiate between objects (as values) and references, as there can be at most (or depending on the language: exactly) a single owner. But even then you may always add a reference for navigating the opposite direction. Doesn't matter at all for languages with garbage collection, as they usually don't even know a concept of ownership. Commented Apr 14, 2016 at 16:16

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.