Paul Gielens:ThoughtsService

another Endpoint to my thoughts

News

Syndication

Ads


Favorites

Projects

Aggregates, Services and Entities

Ayende’s example calculates the cost for an order. For this it needs the order lines associated with the order. Udi brings up an interesting fact about Ayende’s implementation. The order service knows a whole lot about the implementation details of the calculate cost operation on the order. Valid point! For this it optimizes the fetch query for this particular order so that all of the associated order lines are loaded as well. This solution is acceptable only if optimization is an absolute necessity.

I am not so keen on the suggested alternative solution. Cluttering the domain model with different fetch strategies for specific use-case scenarios is a bad idea. I know, I have been there myself!

It is very unlikely that we care about those order lines outside of the context of that particular order. What this example lacks is a clear boundary. We can do this by imposing ownership of the order by marking of the scope for calculating the cost. Order is then acting as the aggregate root and the order line is within its boundary. Since order is an aggregate and should maintain consistency it is loaded eagerly.

A tight connection with the problem domain at hand makes giving good examples for explaining Domain-Driven Design so hard.

Comments

FransBouma said:

#define bad in:

"Cluttering the domain model with different fetch strategies for specific use-case scenarios is a bad idea. "

The functionality element 'calculate total' is a single unit. Placing it somewhere doesn't make it fall apart in multiple elements.

However when you use repositories, you run into the problem that to efficiently produce the data to APPLY the functionality, you have to make repositories aware of eachother.

IMHO then pointing at the functionality element as being bad is silly: the core cause of the whole mess is that the choice for repositories IMPLIES these kind of problems as I've tried to argue on the DDD yahoo group last week.

Also, what everyone seems to forget is that the ordertotal isn't an entity attribute. It's information produced by interpreting entity data. I.o.w. the result of a function.

# March 7, 2007 6:09 AM

p.gielens said:

"The functionality element 'calculate total' is a single unit. Placing it somewhere doesn't make it fall apart in multiple elements."

Fetching is a different concern from that of calculating the cost.

"However when you use repositories, you run into the problem that to efficiently produce the data to APPLY the functionality, you have to make repositories aware of eachother."

You do as soon as you start neglecting the aggregate boundaries. Aggregates go hand in hand with repositories but in isolation create havoc in the domain model. The suggested alternative solution is a great example of this "natural" behavior.

"Also, what everyone seems to forget is that the ordertotal isn't an entity attribute. It's information produced by interpreting entity data. I.o.w. the result of a function."

True in Chen/NIAM. In DDD this is a way to capture meaningful concepts in a model. Since the cost attribute is closely related to, for instance, an invariant rule that the sum of the order lines can't exceed the limit for the order as a whole, it makes a lot of sense to let it influence the way boundaries are being defined in the resulting model.

Another thought... although DDD does in fact need aggregates it doesn't have the absolute need for repositories. Repositories abstract away the resource layer feeding into the model. There is nothing wrong with skipping repositories altogether and tightly couple your model to the resource layer. Assuming your organizations governance model prescribes the usage of a specific tools or a way of dealing with resources.

How does this influence your pov?

# March 7, 2007 7:06 AM

Ayende Rahien said:

Can you post an example with code?

I am afraid that I don't follow so well what you mean here.

# March 7, 2007 2:54 PM

FransBouma said:

"How does this influence your pov?"

Well, I more and more are convinced that repositories do well IF you don't have to work with object graphs. As soon as you have to work with object graphs, repositories will kill your application. Anyone who says 'that's not important', imagine a big box with multiple procs sweating its *ss off because getting the data is so incredibly inefficient.

Aggregates... OK, they make the domain a little more describeable but then again.. without repositories, who needs aggregates?

What struck me was this stupid example from northwind:

order - order detail - product.

It's a logical set of entities, where you could argue if orderdetail is an entity (it's an objectified relation actually between order and product) but the main point is: if Orderdetail is a value object of the aggregate root 'order', how to work with product properly? By referencing the aggregate root 'product' from orderdetail? If so, what does that really mean?

If I take a step back and throw these things all out of the window, does the world then really fall apart and look dim and dark? No not at all. It's still perfectly possible to discuss domain specific material, design domain objects and behavior, relations they have to eachother etc.

I think that's also what Udi argued in Arosa and I then wasn't convinced about his point but I think he does have a point.

# March 7, 2007 3:33 PM

p.gielens said:

For an example see Eric's book page 130 - 135.

public T FindOne(IFetchSpecification fSpec)

{

 fSpec.AddSpan("OrderLines");

 return (T)context.Find(fSpec);

}

The only thing that is different from your example is that the repository is now responsible for (eagerly) loading the order lines. Repositories deal with aggregates only and handle them as a unit.

# March 7, 2007 4:19 PM

p.gielens said:

"without repositories, who needs aggregates"

An object-relational mapper capable of storing the whole object graph and guarantees consistency the model renders repositories and aggregates irrelevant. An argument for aggregates is that they make complex models more manageable.

"By referencing the aggregate root 'product' from orderdetail? If so, what does that really mean?"

It depends on the domain problem at hand. If there is a significant use-case for working with the product, product could be acting as an aggregate too. It is difficult to discuss applying DDD without a context or real world problems, which is the main reason for academic discussions that aren’t bringing us any closer to solving problems.

"I think that's also what Udi argued in Arosa and I then wasn't convinced about his point but I think he does have a point."

What was his point again?

# March 7, 2007 4:53 PM

Ayende Rahien said:

@Paul,

I don't want the order lines in most cases.

Pulling them as well would be just overhead.

The issue is that for _this particular use case_ I need to load the order lines as well.

# March 7, 2007 5:37 PM

Paul Gielens said:

@Ayende

Could you post all stories which involve order, oder line and product (or any other related stuff)? I want to learn more about your problem domain to discus the resulting model and possible implementations.

# March 8, 2007 2:04 AM

FransBouma said:

"An object-relational mapper capable of storing the whole object graph and guarantees consistency the model renders repositories and aggregates irrelevant. An argument for aggregates is that they make complex models more manageable."

But that's just semantics, isn't it?

"It is difficult to discuss applying DDD without a context or real world problems, which is the main reason for academic discussions that aren’t bringing us any closer to solving problems."

Though isn't it true then that DDD is in its core a set of good ideas but you should take it as that: a set of ideas. How you apply these ideas in your own reality, your own projects, that's up to you.

Similar to Agile: the core is: 'adaptive to change'. If that's guaranteed in your work, you're agile. HOW you achieve that isn't important.

"What was his [Udi] point again?"

Why one would need repositories :)

# March 10, 2007 2:30 PM

p.gielens said:

I can think of two good reasons.

1.) Let the domain model drive the database schema. I can recall discussing this face-to-face with you. Also see http://domaindrivendesign.org/articles/archive/rainsberger_jb_2003_10.html

2.) Another layer of abstraction. Also see http://www.martinfowler.com/eaaCatalog/repository.html

And in the second Udi definitelyhas a point! I'm not in favor of the "interfaces" solution. I have never seen it in action, so this is nothing more than a gut feeling for now.

# March 10, 2007 4:05 PM

While True » Blog Archive » O/R mapping and Aggregates said:

Pingback from  While True  » Blog Archive   » O/R mapping and Aggregates

# August 17, 2007 1:29 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)