2

I'm struggling with a DDD concept in designing aggregate roots. I have a Client, which has multiple Projects, Projects have multiple Project assignments, which has multiple Employees. It seems natural to have a ClientRepository, which would manage Project, and not expose a ProjectRepository. After all a Project has to belong to a client. But.... business comes a long and they want a page that has all projects displayed, regardless of client. Basically a dump of the Project table. There is no way to get all Projects from ClientRepository or the ClientDomain object itself, so do you just expose a ProjectRepository in that case?

Just for background my technology stack is Java, Spring, Spring-Data-JPA, Hibernate, although DDD is technology agnostic.

2

You may want to look into the concepts of read models, possibly in combination with a CQRS-style architecture for your bonded context dealing with clients and projects.

The aggregate that contains the business logic would be a so-called write model with the responsibility to change state in the system while preserving business invariants.

The effect of such changes is a matter of implementation and can range from modifying in-memory data to saving data in a database. Or appending events to an event log that will later be used to restore the state if the aggregate (event sourcing).

Having an event mechanism (not necessarily coupled to event sourcing) enables updates of the read models that will be used to retrieve data for external use eg. in an application UI.

While there can be only a single write model to ensure the integrity of business rules, there may be multiple read models that can be updated from various sources.

That said, even a relational database can be used to achieve some of the benefits of separating write and read models. For example, you can have a highly normalized schema for writes and create denormalized views to have a different model for read access.

1

I think according to DDD its not a problem to gather all Projects via the ClientRepository to display them in a (read-only) View. The ClientRepository is not allowed to load Projects directly, so you need to load and traverse all Clients and gather their Projects.

Note that the view is not allowed to trigger (direct) Project modifications. Here you would need the Projects aggregate root object, or make Project an aggregate root.

In some cases it might also be totally ok to bypass DDD and directly access your Projects (via SQL for example). Of course here also the view should be read-only.

  • The ClientRepository is not allowed to load Projects directly, so you need to load and traverse all Clients and gather their Projects. That sounds like a performance nightmare. Perhaps bypassing DDD and straight SQL is the best compromise, but it seems like a major weakness in DDD pattern. – jkratz55 Feb 22 '17 at 14:50
  • I dont think it is a major weakness. I mean many methodologies need to be adapted on a specific problem, and often you need to balance out a perfect solution against just being practical at a few points. I would not overthink this, just make clear that it is a DDD expection and if requirements change refactor to a better solution. I think in the original DDD book its also said you need to be flexible and practical at some points, and always search for deeper models. In this sense using direct SQL - if justified because no better option is availabe atm - somehow fits DDD. – jannikb Mar 12 '17 at 6:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.