Is there a common DDD pattern to deal with under-loading of domain objects?
Asked Answered
K

4

10

Sometimes when working on applications, especially when trying to follow proper OOD and DDD patterns, we end up with domain classes such as Customer. Then we have some repository that will load this object, and everything is nice and clean.

Then the application grows in complexity, and we start optimizing for performance. We often find ourselves in situations, where we do not really need to load, say, a list of full Customer objects, but maybe just IDs and names, or a small subset of properties (for example to display in a grid)

Solutions that I have often seen include:

  1. Under-loading domain objects, so basically we would still use Customer class, but we would use separate repository method to load those, and that repository method would load from database only required fields, and populate corresponding properties in objects. Remaining Customer fields would just remain at their default values. This is simple solution, but can lead to many errors if developer (or existing code) expects certain properties to be loaded.

  2. Purpose-classing where we create classes such as CustomerIdName, CustomerInfo, CustomerHeader that contain only properties we need. This approach could create a large number of classes, but with careful subclassing is workable. It seems like it takes away from ubiquitous domain language concept though.

So is there some generally agreed convention to handle those in DDD world? I tried to google this, but were not able to find anything authoritative.

Or maybe it is just a well-known limitation of classic DDD approach and CQRS or other approaches would be better in those scenarios?

Kerwon answered 5/10, 2015 at 18:27 Comment(0)
L
5

I think second approach is the way to go. We are doing that way in our projects but only for read only DTO classes. As long as you are not using them for insert/update that is just fine I guess.

There is also that answer you maybe interested in:

Lachlan answered 5/10, 2015 at 19:18 Comment(2)
Thank you, the answer you linked to, is exactly the same problem I am facing. I would have to think about this a little more, but the concept of bypassing domain model for certain application queries is a very interesting solution.Kerwon
Also see: Lazy loading is design smellAllergist
G
2

It's a well-known limitation of DDD and CQRS is a very good approach to solve it.

CQRS on the read side is basically solution #2 with all necessary precautions to avoid confusing Read Models with modifiable domain Entities : no Repositories for them, readonly classes, etc.

Giannagianni answered 6/10, 2015 at 10:16 Comment(1)
Thanks, it makes more sense for me nowKerwon
E
0

Have you looked into Entity Framework? They have multiple levels of entity lazy loading: MSDN Post

Exponential answered 5/10, 2015 at 18:32 Comment(1)
Yes, we actually use EF (among other sources, such as external web services). We are actually slowly moving away from lazy loading, as then you have to remember if the domain object you are working with actually came from Entity Framework - and you cannot do certain things, such as serialize it into session, without breaking EF connection.Kerwon
P
0

I don't understand why under loading can be a problem. You know which fields are invalid so can block access/lazy load them

Peltast answered 7/10, 2015 at 20:9 Comment(3)
Ok, here is an example, let say a developer needs to change how customers are loaded on page A - we need now apply specific filter. He discovers there is already method that loads the customer with the given filter so he uses that method. But then during testing it turns out deleted customers are now shown, even though page specifically ignores deleted customers? Why? Well deleted was a boolean property that was not loaded and by default all customers appear as not deleted. This may seem like contrived example but situations like that happen.Kerwon
Lazy loading may be also problematic, couple issues I ran into is: Entity Context already disposed, when view trying to access navigable lazy-loaded property, or invoking lazy loaded property one-by-one in a large list, incurring considerable performance penalty.Kerwon
That all sounds non-issues, i.e. non-functioning implementations. A property that is not loaded cannot be called, the proxy just should return an errorPeltast

© 2022 - 2024 — McMap. All rights reserved.