Discussion:
how to restrict Entity references outside of Agg Root
demonsout123
2009-02-20 04:13:15 UTC
Permalink
"The root is the only member of the AGGREGATE that outside objects are
allowed to hold references to, although objects within the boundary may
hold references to each other. ENTITIES other than the root have local
identity, but that identity needs to be distinguishable only within the
AGGREGATE, because no outside object can ever see it out of the context
of the root ENTITY."
--Eric Evans from Domain-Driven Design


Since I can't control whether a calling object keeps a permanent or
transient reference to an object exposed in a given Aggregate Root, I
assume that the only practical way to enforce this rule is by

1. Not having any publicly accessible Entities in my Aggregate Root
2. Not returning any Entity references from method calls.

So in essence, an Aggregate Root's public interface is comprised only of
command methods (e.g. public void DischargePatient()). If this is
indeed correct, and Entities can never be passed back and forth between
Aggregate Roots, doesn't this severly limit how 2 (or more) Roots would
collaborate together to perform operations that necessarily require the
use of the same Entity instance?
Michael Hart
2009-02-20 04:48:07 UTC
Permalink
Can you give an example of what you mean by two Roots collaborating
using the same Entity? This isn't usually something you'd want.

Remember, the Roots themselves are Entities, so if collaboration needs
to happen, it can happen at that top level with the two Root Entities
(possibly using a collaborating Service).

Cheers,

Michael
Post by demonsout123
"The root is the only member of the AGGREGATE that outside objects
are allowed to hold references to, although objects within the
boundary may hold references to each other. ENTITIES other than the
root have local identity, but that identity needs to be
distinguishable only within the AGGREGATE, because no outside object
can ever see it out of the context of the root ENTITY."
--Eric Evans from Domain-Driven Design
Since I can't control whether a calling object keeps a permanent or
transient reference to an object exposed in a given Aggregate Root,
I assume that the only practical way to enforce this rule is by
• Not having any publicly accessible Entities in my Aggregate Root
• Not returning any Entity references from method calls.
So in essence, an Aggregate Root's public interface is comprised
only of command methods (e.g. public void DischargePatient()). If
this is indeed correct, and Entities can never be passed back and
forth between Aggregate Roots, doesn't this severly limit how 2 (or
more) Roots would collaborate together to perform operations that
necessarily require the use of the same Entity instance?
------------------------------------
demonsout123
2009-02-20 16:25:17 UTC
Permalink
Hi Michael,

Based on some posts I've read here, it seems like there are cases where
Entities do need to be shared between roots, but I don't actually have
an example. [:(]

The closest example I can think of is an aggregate root being consumed
by another aggregate root. I'm still working with the Class
Registration application I presented in my first post. Based on
feedback to that post, I ended up creating 2 Aggregate Roots:

* Student-->Enrollments
* Class-->Enrollments
The Class aggregate root has a method EnrollStudent(Student s). I
assume this is okay because aggregates can hold references to other
aggregates.
Post by Michael Hart
Can you give an example of what you mean by two Roots collaborating
using the same Entity? This isn't usually something you'd want.
Remember, the Roots themselves are Entities, so if collaboration needs
to happen, it can happen at that top level with the two Root Entities
(possibly using a collaborating Service).
Cheers,
Michael
Post by demonsout123
"The root is the only member of the AGGREGATE that outside objects
are allowed to hold references to, although objects within the
boundary may hold references to each other. ENTITIES other than the
root have local identity, but that identity needs to be
distinguishable only within the AGGREGATE, because no outside object
can ever see it out of the context of the root ENTITY."
--Eric Evans from Domain-Driven Design
Since I can't control whether a calling object keeps a permanent or
transient reference to an object exposed in a given Aggregate Root,
I assume that the only practical way to enforce this rule is by
• Not having any publicly accessible Entities in my Aggregate
Root
Post by Michael Hart
Post by demonsout123
• Not returning any Entity references from method calls.
So in essence, an Aggregate Root's public interface is comprised
only of command methods (e.g. public void DischargePatient()). If
this is indeed correct, and Entities can never be passed back and
forth between Aggregate Roots, doesn't this severly limit how 2 (or
more) Roots would collaborate together to perform operations that
necessarily require the use of the same Entity instance?
Sebastian Jancke
2009-02-20 12:12:47 UTC
Permalink
Notice,

that the cited restriction on aggregates refers to persistent
references. Ironically we think again of persistence here ;-)

Direct clients of an aggregate may temporarily hold a reference to an
internal entity. Are they allowed to pass that reference along? I think
not, but cannot recall an exact def here or in the book. To keep things
controlled, I would not pass such a temporary ref outside the client.

-Sebastian
Post by demonsout123
"The root is the only member of the AGGREGATE that outside objects are
allowed to hold references to, although objects within the boundary may
hold references to each other. ENTITIES other than the root have local
identity, but that identity needs to be distinguishable only within the
AGGREGATE, because no outside object can ever see it out of the context
of the root ENTITY."
--Eric Evans from /Domain-Driven Design
/
Since I can't control whether a calling object keeps a permanent or
transient reference to an object exposed in a given *Aggregate Root*, I
assume that the only practical way to enforce this rule is by
1. Not having any publicly accessible Entities in my *Aggregate Root *
2. Not returning any Entity references from method calls.
So in essence, an *Aggregate Root's* public interface is comprised only
of command methods (e.g. public void DischargePatient()). If this is
indeed correct, and Entities can never be passed back and forth between
*Aggregate Roots*, doesn't this severly limit how 2 (or more) *Roots
*would collaborate together to perform operations that necessarily
require the use of the same Entity instance?/
/
------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/domaindrivendesign/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/domaindrivendesign/join
(Yahoo! ID required)

<*> To change settings via email:
mailto:domaindrivendesign-***@yahoogroups.com
mailto:domaindrivendesign-***@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
domaindrivendesign-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Peter Morris
2009-02-20 12:51:13 UTC
Permalink
Post by Sebastian Jancke
that the cited restriction on aggregates refers to persistent
references. Ironically we think again of persistence here ;-)
:-)
Post by Sebastian Jancke
Direct clients of an aggregate may temporarily hold a reference to an
internal entity. Are they allowed to pass that reference along?
If you follow this suggestion then you can pass in-memory instances of
aggregated parts along, but once you do no other instance should hold a
persistent reference to its identity. So for example it would be perfectly
valid to be able to iterate over the lines in a purchase order, but when
identify referencing them (persistence) you would instead reference the
order.


Pete
====
http://mrpmorris.blogspot.com
http://www.capableobjects.com - Think domain, not database



------------------------------------
Sebastian Jancke
2009-02-20 17:09:21 UTC
Permalink
jap.

-Sebastian


------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/domaindrivendesign/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/domaindrivendesign/join
(Yahoo! ID required)

<*> To change settings via email:
mailto:domaindrivendesign-***@yahoogroups.com
mailto:domaindrivendesign-***@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
domaindrivendesign-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
dobrin_s_ivanov
2009-02-20 08:47:50 UTC
Permalink
"Cluster the ENTITIES and VALUE OBJECTS into AGGREGATES and define
boundaries around
each. Choose one ENTITY to be the root of each AGGREGATE, and control
all access to the
objects inside the boundary through the root. Allow external objects to
hold references
to the root only. Transient references to internal members can be passed
out for use
within a single operation only. Because the root controls access, it
cannot be blindsided
by changes to the internals. This arrangement makes it practical to
enforce all
invariants for objects in the AGGREGATE and for the AGGREGATE as a whole
in any state
change."
--Eric Evans from Domain-Driven Design

I assume that the operation is a datasource transaction. So I think you
can have access to any entity you want if your model permits it by (1)
traversing some path starting from the aggregate root and/or (2)
directly obtained by some repository for example within some
transaction.

So, only the persistent store (with its non-transient references)
enforces the rules above strictly where you should have only one type
of inter-aggregate referencies: entity->aggregate-root-entity.
Post by demonsout123
"The root is the only member of the AGGREGATE that outside objects are
allowed to hold references to, although objects within the boundary may
hold references to each other. ENTITIES other than the root have local
identity, but that identity needs to be distinguishable only within the
AGGREGATE, because no outside object can ever see it out of the context
of the root ENTITY."
--Eric Evans from Domain-Driven Design
Since I can't control whether a calling object keeps a permanent or
transient reference to an object exposed in a given Aggregate Root, I
assume that the only practical way to enforce this rule is by
1. Not having any publicly accessible Entities in my Aggregate Root
2. Not returning any Entity references from method calls.
So in essence, an Aggregate Root's public interface is comprised only of
command methods (e.g. public void DischargePatient()). If this is
indeed correct, and Entities can never be passed back and forth between
Aggregate Roots, doesn't this severly limit how 2 (or more) Roots would
collaborate together to perform operations that necessarily require the
use of the same Entity instance?
vvernon_shiftmethod
2009-02-20 17:11:05 UTC
Permalink
Post by dobrin_s_ivanov
Transient references to internal members can be passed
out for use within a single operation only.
Yes, that too. :)
Post by dobrin_s_ivanov
So, only the persistent store (with its non-transient references)
enforces the rules above strictly where you should have only one type
of inter-aggregate referencies: entity->aggregate-root-entity.
Well, you also assure by design that the model doesn't do something
illegal with a transient entity. Even if persistence (if you use
persistence that can support this constraint) ensures the rules are
kept for the entity, if the model is not well designed and reviewed
the attributes of the transient entity could still be stored in
another entity type, which should probably be wrong by design.

Vaughn



------------------------------------
vvernon_shiftmethod
2009-02-20 16:45:59 UTC
Permalink
Post by demonsout123
doesn't this severly limit how 2 (or more) Roots would
collaborate together to perform operations that necessarily
require the use of the same Entity instance?
One observation is that it may be better to model the operations as
value objects. I can't be sure since I don't know your domain, but the
name Operation sounds like it could be identified by its attributes.
Is that possible? If so you could answer an Operation value object
from the aggregate root and no one would get hurt.

Also, if the Operation must be an entity it is possible that the
aggregate root could still answer an Operation as a value object
representation for the sake of sharing. Sometimes its a good idea to
allow entities to be represented as value objects or the sake of
transferring data even around a single bounded context.

HTH,

Vaughn




------------------------------------
nbplopes
2009-02-21 10:28:12 UTC
Permalink
Yes, this is an excellent question.

Here is an example:

http://lh4.ggpht.com/_os9vK9yX6Fc/SZRmhtVp1FI/AAAAAAAAADk/JIAfdjr04aM/
image_thumb[12].png?imgmax=800

I'm looking for guidance and understanding from you guys:

1) What are the aggregate roots.?
2) Why they are the aggregate roots?
3) Finally how would you code business rules in it.

Nuno




------------------------------------
Hadi Hariri
2009-02-21 17:48:39 UTC
Permalink
Post by nbplopes
1) What are the aggregate roots.?
2) Why they are the aggregate roots?
3) Finally how would you code business rules in it.
Nuno,

Forgetting for a moment Eric Evan's book or other ones, or even Google, you
would be amazed with the wealth of information there is here, and the best
part is that it's completely searchable. If you logon to the web, you can
search the message database. Seeing that AR are somewhat common in DDD, I'm
pretty sure it's been discussed a few times so your search is bound to turn
up some threads.

Btw, please don't take this the wrong way. I'm just assuming you might not
be aware of this feature.




------------------------------------
nbplopes
2009-02-21 23:32:10 UTC
Permalink
I've searched the Internet about AR. All the texts explain what an AR
is, but they don't explain what are the advantages of AR and what are
the disavantages!

Or should I assume that the concept is so new that is perfect?

Only by weighting the advantages and disavantages I can decide is it
is good or not for a situation.

Maybe I've came to the wrong forum.

Nuno




------------------------------------
nbplopes
2009-02-21 23:41:41 UTC
Permalink
I even put forward an example to focus the comments to help ideas
coming, I guess that was not good enough.

Nuno



------------------------------------
Michael Hart
2009-02-22 02:32:25 UTC
Permalink
Nuno,
Post by nbplopes
I've searched the Internet about AR. All the texts explain what an AR
is, but they don't explain what are the advantages of AR and what are
the disavantages!
Please do some more research before making statements like this.

http://domaindrivendesign.org/discussion/messageboardarchive/Aggregates.html

http://www.infoq.com/minibooks/domain-driven-design-quickly

The advantages are listed here and in many other places on the net -
if you can't find disadvantages, well it's probably because they're
fairly obvious - as you're being more rigid in your design, it will
feel like you have less flexibility - but it's these particular
flexibilities that get you into trouble in the first place.


------------------------------------
billhamaker
2009-02-23 14:34:49 UTC
Permalink
1. I would say that the only aggregate root is Order + Order Lines.
The reason why you put something in an AR is because it makes for a
simpler conceptual model.

2. There aren't any absolute rules here what you are looking for is
what Eric refers to as a "supple system" but you may learn what that
involves as the domain evolves over time. So a lot depends on how
likely business rules are to change in the futurt. I would generally
expect business rules to be subject to the whims of management and tend
to put them outside of the domain objects as metadata.

Bill
Post by nbplopes
Yes, this is an excellent question.
http://lh4.ggpht.com/_os9vK9yX6Fc/SZRmhtVp1FI/AAAAAAAAADk/JIAfdjr04aM/
image_thumb[12].png?imgmax=800
1) What are the aggregate roots.?
2) Why they are the aggregate roots?
3) Finally how would you code business rules in it.
Nuno
------------------------------------
nbplopes
2009-02-22 22:30:50 UTC
Permalink
When I saw the answers to my questions I could not believe that
they were coming from professional people, so I refrained myself
and tried to figure out a way to answered it positively. So here
is my attempt.

First of all, my main professional objective is to develop the
best software I can develop from my clients according to their
needs. My job is not to promote DDD, FDD, SOM, ORM whatever but to
build software.

As such I don't belong to any camp. I do have some conceptual
artifacts that from experience work better then others. But beuty
is in the eye of the beholder.

I came to DDD through my research about NHibernet, Ayende's work
and more importantly Udi (SAO) on his blog. I don't know them
personally but I like what they write in general. Their
brighteness led me here.

I suspect I'm not the only one in this situation.

The two comments suggested that I haven't done my homework. So
I'll try to dissipate any doupts about that.

As far as I see AR especifically introduces the concept of
Components into the Domain Model. Not so much from the point of
view reusability, but from the point of view of encaspulation
(Composition). Nothing new here. Prior to 2004 I had already read
some texts explaining similar if not identical concepts.

If all objects with the exception of Value Object are aggregate
roots, then the concept would be meaningless. But of course this
scenario is not the common in DDD I guess, so I take this out of
the equation.

So focusing on a scenario were Aggregate Roots are rich..

We know that Composition has hierachical structure (an object that
owns-scopes an object that own-scopes, etc). As such it requires
an hierachical view of both behaviour and information, in other
words knowledge. In this structures information flows mainly
downstream with exceptions rising upstream (events). This has both
advantages and disavantages from a design point of view.

1) Knowledge in general is not hierachical concept, as such when
you "force" Composition into a Domain Model one may indeed
interpreting the Ubiquotous Language (since the Model is an
interpretation of that language) in ways that change its meaning
and dynamics. In other words, you end up with a Model that may not
map reality as required.

2) Invariants is a fancy name for theorems nand corolaries but
with more generic meaning. Busineess rules either are axioms,
theorems or corolaries in a logic system. Anyway, the problem from
a design point of view is that the head of the composition is
often seen as the controller of all business rules in that
composition. It knows everything about the system, it can
potential rule enverything in that system, making aggregates
potentially anemicm delegating rules to them that are not
critical. We all have see that this can be bad (OrderManagers,
SecurityManagers and so on) in several instances.

3) ...

I'm not stating that DDD intent is not good, but by not offering
consistemt guidance about how businesss rules should be
distributed within an Aggregate Root i can only conclude that
either it is trivial or the issue is not well understood.

This is in contrast with SOM. Certain individuals commenting
negatively SOM (Streamlined Object Modeling) approach clearly some
have not grasped the concepts and the problems that are being
tackled in that book. Actually missguided business rule
distribution strategies can be veryfied in several different
instances on thread in this forum.

I don't like to be so abstract in my interventions so I will
present an example.

Say that a company has a chain of hotels and wants to build a
peace to manage inventory on their chanin (Inventory System). An
hotel has an entrance, several flours and two elevators. Each
flour has several rooms, each room several compartments. You have
different types of rooms. One may have just two compartments such
as room and bathroom, other may have a kichen too, a living room,
a mezzanine and so on. Each flour has halls, each hall is equiped
with fire extintors and so on and son. Just focusing on the
reality of a bathroom is already overwhelming (You have soap,
toals, shamppo an other items). Also in first class A rooms you
can only use settin sheets in the bed and other business rules. I
could go on an on describing this but elements are so many and the
time is scarse (Just imagine the biggest hotel you in LV).

Each place in the hotel according to DDD does not have global
identy (I understand the principle). A room, halls, bathroms, etc
etc all have local identity.

If we follow the sugestions on this forum of what should be the
aggregate root in the domain described succintely above (there
would be a lot more to say) then I can only conclude that Hotel is
the Aggregate Root of all places in it. As such any interaction
with say a bathroom must through the Hotel interface (A huge
Interface if you imagine the number of items that can be placed).
Putting a towel in a room, or using a sheet on a bed etc etc.

People here have presentéd arguments against Streamlined Object
Modeling, mainly stating that if you follow the patterns presented
you end up with a system that does not represent the Ubiquitous
Language. Obviously this can come only from people that are still
batteling with basic Domain Modeling concepts and I'll explain, or
with other motifs but building software.

One may argue that the Ubiqutous Language does not translate to
asking the Sheet to put itself in the bedroom bed, it is not
natural (The streamlined object modeling way). True, but it also
does not translate to ask the Hotel to put the sheet in the the
bedroom bed (aHotel.PutSheetInBedroomBed(roomid, ... sheet
info ...)). In reality what happens is that some employee in the
hotel, will go to the elevator, goes down the hall, enter the
room, go to the bed and put the bed sheet there directely! The bed
sheet needs to be according to the Room spec (Class A, ClassB etc
etc) but also acording to the bed spec (size). Then the employee
might log the action in some Log. I uses the bed sheet has an
example but I can use a light bulb.

If i'm looking where a bed Sheet is (has it own Identity and
probably is Aggregate Root or part of one (worst)), I can't ask
the Sheet where it is, simply becouse the sheet can't have a
reference to the bedroom as it is part of the Aggregate Root
Hotel. Even though this would be the most logical, efficient and
direct way to achive this goal.

This leads to a large list of methods in the Hotel to support
multiple types of materials, business logic, behaviours etc etc.
Invariants? Honestely, in a structure has complex has this
Invariants is the least of your problems.

If you are like me, I can only understand fully the implications
of something in contrast with others. But also when I see it
written in code.

Udi Hanan has an article entitled: How to create fully
encapsulated Domain Models (http://www.udidahan.com/2008/02/29/how-
to-create-fully-encapsulated-domain-models/).

A very interesting article has it deals precisely with
distributing business rules in a Domain model. To resolve a
business rule he introduces a concept GamesReportedLost to the
Model derived from Ubiqutous Language. This structure is basically
a list of games lost by a Customer. This list was necessary
becouse of a business rule:

"#3 No games can be added to the cart that the customer had
previously reported lost with regards to their rental membership."

Indeed he is not breaking the Aggregate Root concept when he does
customer.GameReportedLost.Contains(game). He is using a reference
to an aggregate in an Aggregate Root but only in the context of
one operation. So all is good right?

But has Ayende pointed out (first commentr) this list can be
HUGE. Udi answer with a complex solution to say the least. Why?

All to keep the Aggregate Root concept solid IMHO. This when there
was a far easier solution directily coming from the Ubiqutous
Language if we forget Aggregate Roots (a technical concern not a
domain language).

An alternative solution is presented in a article of mine
Distributing business rules when face to face with an Aggregate:
http://movablesharp.blogspot.com/search/?q=UDI

The problem is that my solution breaks the Aggregate Root
boundaries of Customer by asking the Product concept if it was
lost by the customer (Becouse LostGame is an object of the
Customer Aggregate Root). To do this I need to hold a reference to
a product that a customer has lost I think. But in the end of the
day that is the most natural and efficient thing to do (Objects
Think!).

One last note about local identity versus global identity and the
reasoning behind defining Aggregate Roots. (local indenty = > part
of aggregate root => can be only identified locally => the
Aggregate mediates the act of localizing an item given its ID).
This is the kind of reasonling I've been seeing in this forum
often, so execuse me If I don't know better.

Take a Web Page, does it have only a local ID? Or does it also
have a global ID?

I see it has having both! The URL of a web page is the global ID!
In the Ubiqutous Language I mean. I think we all agree that say an
Article in a Blog has global Identity.

On another side, putting a web page in say IIS Web Site, you don't
ask IIS to put it there. I go to the folder and put it there. IIS
does not even know that it is there unless it is requested.

Indeed, any aggregate part of an Aggregate Root can be be
potentially have a Global Identifier, although the concept only
has indentity whebn put into context.

This realization is the very same that sustains for instance the
ability to get hold of a room to but a light bulb in and to ask
the bulb to attact itself to the room.

Why, becouse the bedroom has a global identifier in the hotel
system. It is even more important then an hotel (I can have a room
without an hotel, but for sure I can't have an hotel without a
room).

Anyway, this post is getting long, but sometimes people need more
info to realize "trivial matters".

In DDD especially interested on Bounded Contexts, ContextMaps and
other more advanced concepts that in our industry does require
some "formal" insight. Also I'm very interestin in how it relates
to SOA etc etc. I think Aggregate Roots and Value Objects is a
moot point anyway, more the first the the second. I do Domain
Driven Sofware design all the time. I use the Ubiquotous Language
all the time even before the DDD book came out.

Maybe not the DDD camp way (came after the book). So I came in to
learn the DDD way but I have some concerns. So what? Does that
mean I need to learn how to search the internet or I lack reading
skills?

What do you think?

Nuno




------------------------------------
Eben Roux
2009-02-23 05:58:21 UTC
Permalink
Hey Nuno,

Interesting.

I have a *very* clever buddy. He has been OO-ing for yonks. He
refuses to even consider DDD principles since he reckons they don't
work in practice. He reckons I'll come around :)

Such things concern me. And after reading your post I'm starting to
have reservations about *many* things. We all know that software
engineering is complex and that there are many ways to approach it.

I just feel that sometimes one gets an answer here that proclaims to
be the absolute truth (maybe just my perception). Anything else is
just plain wrong.

Now I don't know *anyone* on the group personally and, therefore,
no-one knows me. So one cannot make assumptions about the knowledge
anyone possesses. Having or not having a blog means very little.

I try to improve software as I go along but things just seem to keep
changing under your feet. This is probably why the software industry
is in such a rubbish condition. I reckon 80+% of system are developed
by folks that don't have the relevant knowledge of system design.
Business folks don't know that. Then after-the-fact they bring in a
'heavyweight' / 'genius' / etc. and expect this person to slap it into
shape: *not* going to happen.

It is quite disheartening.

Regards,
Eben



------------------------------------
Casey Charlton
2009-02-23 07:29:32 UTC
Permalink
If he refuses to even consider something, then he isn't smart, he is
ignorant (in the literal sense). development isn't about absolutes,
but refusing to accept there may be something valuable in something
you don't yet know anything about is foolish, and possibly the worst
kind of person to be a developer.

On your last part you are entirely correct, most developers are not
sufficiently skilled or interested in providing their businesses with
a quality product, and the business has no way to know that. I meet
them time after time in my job, some are open to learning and
improving, some are like your friend.

The less a person knows, the less they can appreciate how little they
know. So those who know least often proclaim to be experts. Now the
quandry given that statement, how do you know you are not one of those
people? ;). (and yes I often apply the question to myself before
anyone takes offence)

Casey Charlton
http://devlicio.us/blogs/casey
Post by Eben Roux
Hey Nuno,
Interesting.
I have a *very* clever buddy. He has been OO-ing for yonks. He
refuses to even consider DDD principles since he reckons they don't
work in practice. He reckons I'll come around :)
Such things concern me. And after reading your post I'm starting to
have reservations about *many* things. We all know that software
engineering is complex and that there are many ways to approach it.
I just feel that sometimes one gets an answer here that proclaims to
be the absolute truth (maybe just my perception). Anything else is
just plain wrong.
Now I don't know *anyone* on the group personally and, therefore,
no-one knows me. So one cannot make assumptions about the knowledge
anyone possesses. Having or not having a blog means very little.
I try to improve software as I go along but things just seem to keep
changing under your feet. This is probably why the software industry
is in such a rubbish condition. I reckon 80+% of system are developed
by folks that don't have the relevant knowledge of system design.
Business folks don't know that. Then after-the-fact they bring in a
'heavyweight' / 'genius' / etc. and expect this person to slap it into
shape: *not* going to happen.
It is quite disheartening.
Regards,
Eben
Ian Chamberlain
2009-02-23 09:06:59 UTC
Permalink
See http://www.apa.org/journals/features/psp7761121.pdf.

Competency is the bane of software development because there is no formal
method for ascertaining who is competent and who is not.

When participating in any newsgroup there is no guarantee that the person
offering the advice knows what they are talking about. However, IMO, the
discussions one finds online are still amoingst the best ways to learn, you
just have to do a bit of due diligence about who is doing the talking and
try things out and prove them for yourself.

Regards

Ian Chamberlain



From: ***@yahoogroups.com
[mailto:***@yahoogroups.com] On Behalf Of Casey Charlton
Sent: 23 February 2009 07:30
To: ***@yahoogroups.com
Subject: Re: [domaindrivendesign] Re: how to restrict Entity references
outside of Agg Root



If he refuses to even consider something, then he isn't smart, he is
ignorant (in the literal sense). development isn't about absolutes, but
refusing to accept there may be something valuable in something you don't
yet know anything about is foolish, and possibly the worst kind of person to
be a developer.



On your last part you are entirely correct, most developers are not
sufficiently skilled or interested in providing their businesses with a
quality product, and the business has no way to know that. I meet them time
after time in my job, some are open to learning and improving, some are like
your friend.



The less a person knows, the less they can appreciate how little they know.
So those who know least often proclaim to be experts. Now the quandry given
that statement, how do you know you are not one of those people? ;). (and
yes I often apply the question to myself before anyone takes offence)

Casey Charlton

http://devlicio.us/blogs/casey




On 23 Feb 2009, at 05:58, "Eben Roux" <***@bbd.co.za> wrote:

Hey Nuno,

Interesting.

I have a *very* clever buddy. He has been OO-ing for yonks. He
refuses to even consider DDD principles since he reckons they don't
work in practice. He reckons I'll come around :)

Such things concern me. And after reading your post I'm starting to
have reservations about *many* things. We all know that software
engineering is complex and that there are many ways to approach it.

I just feel that sometimes one gets an answer here that proclaims to
be the absolute truth (maybe just my perception). Anything else is
just plain wrong.

Now I don't know *anyone* on the group personally and, therefore,
no-one knows me. So one cannot make assumptions about the knowledge
anyone possesses. Having or not having a blog means very little.

I try to improve software as I go along but things just seem to keep
changing under your feet. This is probably why the software industry
is in such a rubbish condition. I reckon 80+% of system are developed
by folks that don't have the relevant knowledge of system design.
Business folks don't know that. Then after-the-fact they bring in a
'heavyweight' / 'genius' / etc. and expect this person to slap it into
shape: *not* going to happen.

It is quite disheartening.

Regards,
Eben



No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.0.237 / Virus Database: 270.10.23/1951 - Release Date: 02/20/09
19:22:00
nbplopes
2009-02-23 09:23:36 UTC
Permalink
1) Just becouse I'm inclined not to be accept a concept as an
absolute thing such as AR it doesn't mean that I don't see the
benefits of it in some cases.

2) DDD is not just Aggregate Roots, there are plenty of stuff that
seams to be good. The good stuff (IMHO) I read it and understand
almost straight forward.

The main thing that I'm battling is AR as a core artifact of
design, as such the questions I've put forward. For instance, I
think at modeling time AR is very bad. It blinds the modeller or
developer from better options. "How can you define a boundary if
you don't have yet enough information to do it".

I'm very open minded (there is no other way to learn). Also I'm
not an expert in OO. I'm just a software developer that is trying
to improve the way he does stuff.

So I think I made some honest and valid questions. Maybe I'm
missing the point, so I'm looking for clarification.

Nuno









------------------------------------
dobrin_s_ivanov
2009-02-23 09:59:27 UTC
Permalink
Post by nbplopes
The main thing that I'm battling is AR as a core artifact of
design, as such the questions I've put forward. For instance, I
think at modeling time AR is very bad. It blinds the modeller or
developer from better options. "How can you define a boundary if
you don't have yet enough information to do it".
As I understood from DDD book the aggregate bounderies are considered
some of the final steps in the modelling...
Post by nbplopes
From my practice I think the aggregates made some simplification in
your model, but more on its persistence view or when you want to
replicate your model on more then one repository (sending messages
containing only the updated/created whole aggregate instance). Like
you have Repository only for each aggregate root and no more,
cascading rules for inter/intra aggregate referencies, only lazy
referencies for inter aggregate relations...
Also the persistence model (only relational in my practice) enforces
the rule for inter-aggregate referencies - no internal entities can be
referenced from outside. This one is the hardest for me. =>

It often turns out that there is some entity shared between two
aggregates. I solve this by (1) having global identity for this shared
internal entity and (2) give write access and invariant enforcement
only to one of the aggregate roots, so that the others just refer it
and no more.

How do you solve the entities that appear to be shared by two (or
more) aggregates?



------------------------------------
Hadi Hariri
2009-02-23 09:19:28 UTC
Permalink
Post by nbplopes
When I saw the answers to my questions I could not believe that
they were coming from professional people, so I refrained myself
and tried to figure out a way to answered it positively. So here
is my attempt.
I'm not sure if you're referring to my response, but just to set the record
straight,
your initial questions were short and to the point: What is AR, what are
AR's advantages.

Seeing as both those topics have been discussed many times, I was merely
referring you to
the search facilities of this forum. It's not my place, intention or desire
to
judge what you know or might not know or whether you've done your homework.

I apologize if you misunderstood this, but I think I made it pretty clear in
my message.







------------------------------------
Peter Morris
2009-02-23 09:49:05 UTC
Permalink
Hi Nuno

For me an aggregate root is a pattern, one that you can use some/all of.

Sometimes I have found myself updating a composite part of a structure.
When I do this it makes that instance dirty and therefore I validate it
before updating. The problem I have seen in the past though is that I am
altering a single part of a logically larger object which must remain valid
as a whole. Having two people alter different parts of a whole in isolation
can easily have them both performing an update which leaves the whole
invalid, but to each person it looks valid, so it's not until someone next
retrieves it from the DB that the problem is identified. In this kind of
situation you'd use the "aggregate root" approach so that you can only
fetch/update the head of the structure, this way the entire structure is
validated when you update, and if two people try to update at the same time
one will experience a locking conflict.

The other part of the AggRoot is to not have associations directly to
composite parts. In general I don't agree with this. I assume it is to
stop another object from updating its values and then saving it, skipping
the validation of the whole. As long as you still fetch / update the
structure as a whole I can't see what problems you could possibly have from
referencing a composite part directly.

I have used the "no reference" suggestion once though. I had a structure
where head represented a class and the parts represented properties. I had
Instances which associated with the Class and the Instance had Property
Values. Initially I had a link from Instance to Class and PropertyValue to
Property. This didn't feel very clean to me because there wasn't a single
way of determining the class, I couldn't help thinking

"what if someone screws something up and connects PropertyValue to a
Property where this.Property.Class != this.Instance.Class?"

but when it came to re-importing the Class objects + their properties (they
are all imported) I might discover that a BooleanProperty has changed to an
IntegerProperty, and as a consequence would have to also change all
BooleanPropertyValues to IntegerPropertyValue. At the point I create a new
IntegerProperty and then have to migrate all PropertyValues it was messy
having a direct association to the parts (PropertyValues). This was because
it was tempting to work directly with the Property's PropertyValues
collection instead of the Instance AggRoot. Once the new IntegerProperty
was created I would have to delete every relevent BoolPropertyValue and
replace it with an IntegerPropertyValue, but this would have meant that not
only do I convert the value of BoolPropertyValue to IntegerPropertyValue but
I would now also need to reassociate the new composite parts.

It was all looking pretty messy :-)

So instead I made the association between the composite parts
non-persistent. I made them derived instead. I now have an easy way to
access PropertyValue.Property, but it's looked up by navigating

this.Instance.Class.GetPropertyByName(this.Name);


In the case of a PurchaseOrder/PurchaseOrderLine I might again be tempted to
use the same approach, but in some circumstances I might decide that I *do*
want direct references to composite parts, especially if it is a complex
structure and about 5 levels deep. Using your Hotel example I don't believe
the Hotel is the AggRoot. You must differential between an AggRoot and the
head of a composite structure. In this case the Hotel is the head of the
composite structure (composite parts cannot exist without the Hotel), but
individual rooms are the AggRoots. This is because

01: When you save an AggRoot you check for conflicts. Having the Hotel as
the AggRoot would mean that any operations on a room (book
in/out/reservation/cancellation) would conflict at Hotel level.
02: A booking is for a room. Sure it is for a room in a specific hotel, but
that doesn't mean the room doesn't have its own identity.

Consider a scenario where there are 3 Rooms on the top floor. It is decided
to knock two Rooms 1 & 2 into a single Room. Room 3 now becomes Room 2.
Historical bookings would say that people in Room 1 stayed in a massive
room, and people who stayed in Room 3 didn't stay anywhere. Sure you could
get around this by introducing a HotelConfiguration class but Hotels don't
change often enough to warrant this surely.

So. To summarise:

01: Don't confuse composite structures with aggregate roots.
02: If you need references to parts of the structure you are probably
looking at a composite structure and not an aggregate root.
03: In my opinion you *can* still have references to parts of of aggregate
root, just make sure you perform persistence operations using the head of
the AggRoot to ensure validity.
04: Don't automatically add associations to agg-parts, consider if you can
use a local reference such as "Line 3" on an order. However, I'd use this
approach sparingly because derived associations obviously don't work in a DB
and if you find yourself querying something which requires a join between
two agg-parts you might find the query quite complex.

I'm not one for following "rules" blindly. Rules to me are suggestions, if
I want to walk on the grass then I shall :-)


Pete
====
http://mrpmorris.blogspot.com



------------------------------------
nbplopes
2009-02-23 13:12:34 UTC
Permalink
Thank you Pete for your answers.

1) First Paragraph:

Using AR to deal with conflicting business rules amongst aggregates
makes sense considering persistance. In that sense I see that an
Aggregate Root is NOT equal to the head of a composition (light bulb in
my head).

What always baffled me is that at one hand DDD states that the Domain
Model implementation should be persistance unaware, at the other one of
the core patterns for the Domain Model seam built to deal with the
underlying persistance architecture. Repositories only don't cut it.

I guess it all comes down to being practical.

2) Second Paragraph:

Yes that makes more sense if the AR the entity checks conflicting
rules. Nevertheless messy from a rule distribution point of view.

3) "what if someone screws something up and connects PropertyValue to a
Property where this.Property.Class != this.Instance.Class?"

The property class would reject the value IMHO. You need some type
validation and that should be in the Class as it is the entity that
defines it.

Say for instance:

IntValue aPV = new IntValue(10); // int is a subclass or interface -
property value
instance["propertyName"].SetValue(aPV);

Now the operation set value;

... on the PropertyValue class

void SetValue(Value aV)
{
this.PropertyClass.TestSetPropertConflict(aV);
this.Value = aPV;
}

class PropertyClass .....

void void TestSetPropertyValueTypeConflict(Value aPV)
{
if (this.PropertyType != aV.ValueType)
{
throw new Exception("The type of Value does not match the type of
the Property"
}
}

...


As for the rest I'm not sure I follow. If some instance has a direct
reference to a property and change its value for sure that would be
rejected. For instance;

IntValue aPV = new IntValue(10); // int is a subclass of property value
this.ReferenceToAPropertyOfAnotherClass.SetValue(aPV);

Bang.

"this.Instance.Class.GetPropertyByName(this.Name);"

I suppose that the code above does not resolve that.

IntValue aPV = new IntValue(10); // int is a subclass of property value
this.Instance.Class.SetPropertyByName(this.Name, aPV);

Would bang since the type of the property has changed from BooleanValue
to IntValue.

Anyway,

I think I already got part source of my confusing regarding the AR
concept. An AR "pattern" is driven by conflicting business rules and
persistance rather then the Domain. If that is the case it makes much
more sense.

I must say that the drive cannot be extrapolated from the definition:
http://domaindrivendesign.org/discussion/messageboardarchive/Aggregates.
html

Simply state: "It is difficult to guarantee the consistency of changes
to objects in a model with complex associations."

The way I'm used do stuff (without using AR) it is not difficult at all
even in a scenario were you have complex associations (in most cases).
It easy to test etc etc.

Looking at it now, although I see certain scenarios where an AR is
probably the best solution (where you have aggregate roots stored in
different data sources, un-usual in most enteprise environments I
worked with, Top Banks, Insurance et al in PT), in other scenarios IMHO
is a cannon to kill a fly.

Furthermore it does not address scenarios where you have conflicting
business rules beween two Aggregate Roots.

I would be glad to share what I do to solve this if you are interested.
Especially becouse it simplefies development greately where hall
entities share a common data source (most of the apps out there).

Maybe that is for another topic.

Nuno













------------------------------------
Peter Morris
2009-02-23 14:32:00 UTC
Permalink
Hi Nuno
What always baffled me is that at one hand DDD states that the Domain
Model implementation should be persistance unaware, at the other one of
the core patterns for the Domain Model seam built to deal with the
underlying persistance architecture. Repositories only don't cut it.
<<

I think that's why the additional "don't associate to aggregated parts" part
is there. Bascially you don't have order/lines, you have a complex "Order"
object. The domain remains persistence ignorant, its the services that are
aware of the fact.
Yes that makes more sense if the AR the entity checks conflicting
rules. Nevertheless messy from a rule distribution point of view.
<<

The rules can still be on the aggregated parts, you are just ensuring that
the entire structure is valid by validating all of it. Also by updating the
aggregate root you are able to detect when two people update the same
aggregate at the same time, whereas if you update parts separately you can't
(two people add an aggregated part at the same time, the combination exceeds
some limit).

[Most stuff about PropertyValue snipped, mainly because it's like mixing
work and play :-)]

The main reason I went for "don't reference an aggregated-part" in this case
was when the newly imported definition says that BooleanProperty "IsActive"
is now an IntegerProperty. I have to delete the original BooleanProperty
and create a new IntegerProperty in its place. In addition to that I would
have to take every BooleanPropertyValue in its PropertyValues and
reassociate them with the new property. It just started to get messy, and
now that mess is gone completely.
I think I already got part source of my confusing regarding the AR
concept. An AR "pattern" is driven by conflicting business rules and
persistance rather then the Domain. If that is the case it makes much
more sense.
<<

In my opinion, that is exactly the case.
I must say that the drive cannot be extrapolated from the definition:
http://domaindrivendesign.org/discussion/messageboardarchive/Aggregates.
html
<<

I must confess that it was a conclusion I came to rather than one I read
about. I came to it because

01: The AR concept as I had read it didn't make enough sense to me.
02: Experiencing multi-users updating agg-parts led me a long time ago to
ensure the agg-root was also update so I could detect conflicts. I just
never had a name for "the parent object".
Furthermore it does not address scenarios where you have conflicting
business rules beween two Aggregate Roots.
<<

No it doesn't, and I've mentioned this subject myself. The solution seems
to require locking the other object when you retrieve it in order to
validate against it.
Post by nbplopes
I would be glad to share what I do to solve this if you are interested.
I certainly would be interested. If I consider it rubbish I am more than
capable of forgetting it completely :-D


Pete
====
http://mrpmorris.blogspot.com



------------------------------------
dobrin_s_ivanov
2009-02-24 08:08:46 UTC
Permalink
Post by Peter Morris
I have used the "no reference" suggestion once though. I had a structure
where head represented a class and the parts represented properties.
I had
Post by Peter Morris
Instances which associated with the Class and the Instance had Property
Values. Initially I had a link from Instance to Class and
PropertyValue to
Post by Peter Morris
Property. This didn't feel very clean to me because there wasn't a single
way of determining the class, I couldn't help thinking
"what if someone screws something up and connects PropertyValue to a
Property where this.Property.Class != this.Instance.Class?"
I have had a similar model. But here the bigger problem I think is
when you have a PropertyValue that does not correspond to Property.
So, I still do not see advantage to make this relation derived.
Of course you can decide which rules you enforce only at the domain
model level and/or/both persistence level. Until now I have used only
relational db for persistence and I like to use its build-in
constraints whenever possible.

So, here I choose Instance and Class to be AggRoots and Property to be
shared entity between them, but only the Class have write access to it.



------------------------------------
demonsout123
2009-02-25 02:32:17 UTC
Permalink
Thanks to everyone for contributing to this thread. It appears to
have generated some lively debate and, more importantly, a lot of
great ideas.



------------------------------------

Loading...