Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

dependency, association, aggregation

2 views
Skip to first unread message

Kovanan

unread,
Feb 9, 2003, 11:47:13 PM2/9/03
to
I am not very clear on when I should use dependency, when association, and
when aggregation. Could you tell me what the rule is for deciding which one
of them is to be used when?

Thanks


Phlip

unread,
Feb 10, 2003, 12:02:49 AM2/10/03
to
Kovanan wrote:

In UML? or in real code?

In UML, I suspect that there are two kinds of lines. The one with an open
arrowhead means "inherits", and the one without means "can send messages
to". "Dependency" is either kind of line.

When drawing UML, forget the details. Make a picture of the design you have,
or that you think you need.

In real code, use the >weakest< kind of anything in preference to anything
stronger. "Has a reference to" (association) is weaker than "Owns as a
member" (aggregation), so prefer the former without need for the latter.

But this could just be the Guinness Stout talking.

--
Phlip
http://www.greencheese.org/LucidScheming
-- "The Epiphany of the Epiphenomenon of the Epiphysis"
- some jerk-off maliciously pretending to be Henry Miller --

Daniel T.

unread,
Feb 10, 2003, 8:06:04 AM2/10/03
to
"Kovanan" <som...@microsoft.com> wrote:

For the below, I'm using the variation of OMT used by Gamma &al. in the
book "Design Patterns"

[A]- - ->[B]
Dependency means that class B must be accessable to class A. Objects of
class A, either create objects of class B, and/or call static methods of
class B.

[A]----->[B]
Association means that objects of class A send messages to objects of
class B.

[A]<>--->[B]
Aggregation also means that objects of class A send messages to objects
of class B, but in this case objects of class A have exclusive
priviliges to the class B objects they send messages to, ie no other
object may send messages to the aggregate, at least not while the
relationship holds.

Giovanni Asproni

unread,
Feb 10, 2003, 1:18:40 PM2/10/03
to

> [A]<>--->[B]
> Aggregation also means that objects of class A send messages to objects
> of class B, but in this case objects of class A have exclusive
> priviliges to the class B objects they send messages to, ie no other
> object may send messages to the aggregate, at least not while the
> relationship holds.

I think the above statement is not correct. In fact the aggregation
states only an whole/part relationship, but doesn't imply anything more.
The whole is not even necessarily responsible of the lifetime of the parts.
Nothe that in UML it is perfectly legal to have [A]<>--->[B]<---<>[C].
Both A and C can send messages to C possibily at the "same time".

Giovanni

Giovanni Asproni

unread,
Feb 10, 2003, 1:21:40 PM2/10/03
to Giovanni Asproni

The above line should read: Both A and C can send messages to B

Giovanni Asproni

unread,
Feb 10, 2003, 1:21:55 PM2/10/03
to Giovanni Asproni

The above line should read: Both A and C can send messages to B

Giovanni Asproni

unread,
Feb 10, 2003, 1:23:06 PM2/10/03
to
The above line should read - Both A and C can send messages to B
possibily at the "same time" -

Giovanni


Q

unread,
Feb 10, 2003, 1:25:28 PM2/10/03
to
"Giovanni Asproni" <aspro...@ebiME.ac.uk> wrote in message
news:3E47ED00...@ebiME.ac.uk...

It sounds like Daniel T was describing composition, a stronger form of
aggregation. The UML shows the diamond as solid [ie. filled in].

H. S. Lahman

unread,
Feb 10, 2003, 1:41:17 PM2/10/03
to
Responding to Kovanan...

> I am not very clear on when I should use dependency, when association, and
> when aggregation. Could you tell me what the rule is for deciding which one
> of them is to be used when?

Assuming we are referring to UML...

Dependency: indicates a semantic dependency of one object on another.
The dependency is at the level of specification. From the view of
clients, one object's specification includes some or all of the
dependent object's specification That is, an object cannot fulfill its
responsibilities without collaborating specifically with the arrowhead
object. The most common use is to identify objects that are embedded in
other objects as part of their private implementation (e.g., String,
Array, etc.).

Association: indicates a logical relationship between objects. The
relationship represents some kind of correspondence between members of
each set. Note that one can have multiple associations between two
classes. In that case each relationship represents a different
correspondence between members (identified by the discriminator). If
there is an arrowhead the relationship is one-way. The vast majority of
relationships are associations. The most common use is to identify
communications among objects.

Aggregation: a special form of association where the relationship is
logically one of whole/part. That conveys a stronger notion of
association but currently there is nothing in the UML definition that
would cause it to be implemented differently than a simple 1:*
association. So the relationship simply conveys additional problem
space importance of the relationship for model comprehensibility.

Composition: a stronger form of aggregation where the whole/part
relationship also implies coexistence (i.e., the whole and parts live
and die together).


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
h...@pathfindersol.com
Pathfinder Solutions -- We Make UML Work
http://www.pathfindersol.com
(888)-OOA-PATH


Roger L. Cauvin

unread,
Feb 10, 2003, 2:21:41 PM2/10/03
to
"Kovanan" <som...@microsoft.com> wrote in message
news:l9G1a.58548$HN5.2...@rwcrnsc51.ops.asp.att.net...

> I am not very clear on when I should use dependency, when
> association, and when aggregation. Could you tell me what
> the rule is for deciding which one of them is to be used when?

You'll find that even experienced UML modelers have different views of the
rules for using dependency, association, and aggregation in a class diagram.
This confusion is largely due to the fact that the UML specification spreads
the definitions (particularly of "dependency") over several different
sections. I suspect that some modelers have also become attached to their
preconceived notions and are reluctant to accept a different interpretation.
Later in this message I piece together the different sections to show what
in my opinion is a compelling explication of "dependency". But first, here
are the definitions based on my interpretation of the UML specification:

dependency - the implementation or functioning of a class or its instances
refers to another class or its instances (but does not maintain a reference
as a static field or instance variable to the other class or instance).
Example: a class that has a static or instance method that instantiates,
calls a method of, or accepts an argument of, another class or instance of
that other class.

ordinary association - a class or its instances include as a static field or
instance variable a reference to another class or instance of that other
class (but does not necessarily imply a part-whole relationship).

aggregation - an association that implies a part-whole relationship (but one
in which the lifetime of the part does not depend on the lifetime of the
whole). The difference between aggregation and ordinary association is
purely conceptual.

composition (a.k.a. composite aggregation) - aggregation in which the
lifetime of the part depends on the lifetime of the whole. Example: a
class declares an instance variable by value.

Now for the excerpts from the UML that are relevant to the definition of
"dependency":

UML 1.4, Section 2.5.2.15:

"A dependency states that the implementation or functioning of one or more
elements requires the presence of one or more other elements.

In the metamodel, a Dependency is a directed relationship from a client (or
clients) to a supplier (or suppliers) stating that the client is dependent
on the supplier; that is, the client element requires the presence and
knowledge of the supplier element.

The kinds of Dependency are Abstraction, Binding, Permission, and Usage.
Various stereotypes of those elements are predefined."

UML 1.4, Section 2.5.2.40:

"In the metamodel, a Usage is a Dependency in which the client requires the
presence of the supplier. How the client uses the supplier, such as a class
calling an operation of another class, a method having an argument of
another class, and a method from a class instantiating another class, is
defined in the description of the particular Usage stereotype."

UML 1.4, Section 2.3.4:

"When referring to an instance of some metaclass, we often omit the word
'instance.' For example, instead of saying 'a Class instance' or 'an
Association instance,' we just say 'a Class' or 'an Association.' By
prefixing it with an 'a' or 'an,' assume that we mean 'an instance of.' In
the same way, by saying something like 'Elements' we mean 'a set (or the
set) of instances of the metaclass Element.'"

---
Roger L. Cauvin
nospam...@cauvin.org (omit the "nospam_" part)


Daniel T.

unread,
Feb 10, 2003, 2:41:32 PM2/10/03
to
Giovanni Asproni <aspro...@ebiME.ac.uk> wrote:

My statement is correct. Please note that at the beginning of my message
I stated that I was using the variation of OMT used in the book "Design
Patterns" *not* UML.

For UML the difference between association and aggregation are so small
as to be meaningless, and composition is only for non-garbage collected
languages... (ie an implementation detail.)

Daniel T.

unread,
Feb 10, 2003, 2:44:44 PM2/10/03
to
"Q" <nos...@nospam.net> wrote:

> "Giovanni Asproni" <aspro...@ebiME.ac.uk> wrote:


>
> > Daniel T. wrote:
> >
> > > [A]<>--->[B]
> > > Aggregation also means that objects of class A send messages to objects
> > > of class B, but in this case objects of class A have exclusive
> > > priviliges to the class B objects they send messages to, ie no other
> > > object may send messages to the aggregate, at least not while the
> > > relationship holds.
> >
> > I think the above statement is not correct. In fact the aggregation
> > states only an whole/part relationship, but doesn't imply anything more.
> > The whole is not even necessarily responsible of the lifetime of the
> > parts.
> > Nothe that in UML it is perfectly legal to have [A]<>--->[B]<---<>[C].
> > Both A and C can send messages to C possibily at the "same time".
>

> It sounds like Daniel T was describing composition, a stronger form of
> aggregation. The UML shows the diamond as solid [ie. filled in].

No, I wasn't. I wasn't using UML at all. In any case my statement
wouldn't apply to UML's composition relationship because even there, the
object can recieve messages from more than one client object. The
composition diamond only covers lifetime issues, not message passing
issues.

Glen

unread,
Feb 10, 2003, 9:32:39 PM2/10/03
to

H. S. Lahman wrote:


>
> Aggregation: a special form of association where the relationship is
> logically one of whole/part. That conveys a stronger notion of
> association but currently there is nothing in the UML definition that
> would cause it to be implemented differently than a simple 1:*
> association. So the relationship simply conveys additional problem
> space importance of the relationship for model comprehensibility.
>
> Composition: a stronger form of aggregation where the whole/part
> relationship also implies coexistence (i.e., the whole and parts live
> and die together).
>
>


Thats interesting- It didn't know there was a distinction.

If you have something where you can add of subtract parts after creation
is it still considered a composition if the composite is destroyed or
'invalid' when it contains no parts?


So maybe you had a Airplane class. It Has Missile objects on creation
but the missiles can be subtracted. It also contains Wing Objects and
there alway must be two of them. Some objects are required but some
aren't. There is no method that removes wings.

It it a composite or just an aggregate?

Glen.

Giovanni Asproni

unread,
Feb 11, 2003, 3:14:45 AM2/11/03
to
Daniel T. wrote:
> Giovanni Asproni <aspro...@ebiME.ac.uk> wrote:
>
>
>>>[A]<>--->[B]
>>>Aggregation also means that objects of class A send messages to objects
>>>of class B, but in this case objects of class A have exclusive
>>>priviliges to the class B objects they send messages to, ie no other
>>>object may send messages to the aggregate, at least not while the
>>>relationship holds.
>>
>>I think the above statement is not correct. In fact the aggregation
>>states only an whole/part relationship, but doesn't imply anything more.
>>The whole is not even necessarily responsible of the lifetime of the parts.
>>Nothe that in UML it is perfectly legal to have [A]<>--->[B]<---<>[C].
>>Both A and C can send messages to C possibily at the "same time".
>
>
> My statement is correct. Please note that at the beginning of my message
> I stated that I was using the variation of OMT used in the book "Design
> Patterns" *not* UML.
I'm afraid in the previous message I switched to UML mode automatically
after reading the subject of the mail, I'm sorrry for that :-(.
In any case I had a look at the GOF book to understand your point. What
they call aggregation is very similar to UML composition (A is
responsible for the lifetime of B). But, again, a relation of this kind
[A]<>--->[B]<---[C] is perfectly valid, since the only implication of
that kind of aggregation is that A is responsible for the lifetime of B.
There is an example of the structure I describe also in the GOF book,
check the structure of the Flyweight pattern at page 198: the "client"
can send messages to the "Flyweight" that is part of a "FlyweightFactory".

Giovanni.

Q

unread,
Feb 11, 2003, 6:48:53 AM2/11/03
to
"Daniel T." <postm...@earthlink.net> wrote in message
news:postmaster-9217B...@nnrp03.earthlink.net...

Like Giovanni, I too am sorry for upsetting you Daniel T. Since UML became
mainstream I had forgotten about other derivations [so subconsciously
avoided your important OMT reference].

In UML, the difference between aggregation and composition is important. The
original poster, Kovanan, may not realise this, so hopefully the following
concrete example may help:

In double-entry accounting, an entry should not exist without an account.
Futhermore, it should only be associated with one account. It is important
[in UML] that the collection of entries that an account holds is shown as a
Composition. The implementer will then ensure that an entry cannot be
created without being associated with an account, and that it will be
deleted if the account is deleted.

If the implementer saw an Aggregation mark, they may implement it in a way
that may break the contract.

Daniel T.

unread,
Feb 11, 2003, 12:45:31 PM2/11/03
to
In article <3E48B0F5...@MEebi.ac.uk>,
Giovanni Asproni <aspro...@MEebi.ac.uk> wrote:

Ack! You are right, the Flyweight pattern is broken. A beter method
would be for the FlyweightFactory to have an Operation(key,
extrinsicState) method which the client uses. Then the factory would
forward the call to the approprate Flyweight object. One might consider
simply removing the diamond, turning the aggrigation relationship into
an association, but this isn't correct, because FlyweightFactory never
sends messages to Flyweight objects, which would mean the relationship
would become a dependency, even here one would have to ask, why the
dependecy exists. The FlyweightFactory doesn't actually create Flyweight
object, nor does it send messages to them...

The reason I take it to mean that the Flyweight pattern is broken is
because several other patterns (for example Decorator) depend on
exclusive access to the contained objects.

In fact, lifetime issues are purly an implementation detail and need not
be represented on a high level document like a diagram. However
exclusive access is not an implementation detail, it is a very important
concept at the design level. It shows us that the contained object's
existance can be ignored by the containers clients.

The problem I have is that because [A]<#>--->[B]<---[C] is valid UML, we
end up in a situation where the diamond means absolutly nothing at the
design level...

Daniel T.

unread,
Feb 11, 2003, 12:57:52 PM2/11/03
to
"Q" <nos...@nospam.net> wrote:

> "Daniel T." <postm...@earthlink.net> wrote:
>
> > Giovanni Asproni <aspro...@ebiME.ac.uk> wrote:
> >
> > > > [A]<>--->[B]
> > > > Aggregation also means that objects of class A send messages to
> objects
> > > > of class B, but in this case objects of class A have exclusive
> > > > priviliges to the class B objects they send messages to, ie no other
> > > > object may send messages to the aggregate, at least not while the
> > > > relationship holds.
> > >
> > > I think the above statement is not correct. In fact the aggregation
> > > states only an whole/part relationship, but doesn't imply anything more.
> > > The whole is not even necessarily responsible of the lifetime of the
> parts.
> > > Nothe that in UML it is perfectly legal to have [A]<>--->[B]<---<>[C].
> > > Both A and C can send messages to C possibily at the "same time".
> >
> > My statement is correct. Please note that at the beginning of my message
> > I stated that I was using the variation of OMT used in the book "Design
> > Patterns" *not* UML.
> >
> > For UML the difference between association and aggregation are so small
> > as to be meaningless, and composition is only for non-garbage collected
> > languages... (ie an implementation detail.)
>
> Like Giovanni, I too am sorry for upsetting you Daniel T. Since UML became
> mainstream I had forgotten about other derivations [so subconsciously
> avoided your important OMT reference].

I'm not upset with you or Giovanni. I'm a little upset with UML though.
I like my diamonds to mean something but they stripped the meaning out
of them. :-(


> In UML, the difference between aggregation and composition is important. The
> original poster, Kovanan, may not realise this, so hopefully the following
> concrete example may help:

I don't agree. In UML the differences between association, aggregation,
and composition are minor. The only special bit is that composition
brings in an implementation detail that is unnecessary at the design
level.


> In double-entry accounting, an entry should not exist without an account.
> Futhermore, it should only be associated with one account. It is important
> [in UML] that the collection of entries that an account holds is shown as a
> Composition. The implementer will then ensure that an entry cannot be
> created without being associated with an account, and that it will be
> deleted if the account is deleted.

1 *
[Account]-------[Entry]

Represents the above requirement just fine. No need for a composition
relationship here... Come to think of it, aren't all entries associated
with two accounts (the account where the money is being taken out, and
the account in which it is being added?)

H. S. Lahman

unread,
Feb 11, 2003, 3:13:36 PM2/11/03
to
Responding to Glen...

>> Aggregation: a special form of association where the relationship is
>> logically one of whole/part. That conveys a stronger notion of
>> association but currently there is nothing in the UML definition that
>> would cause it to be implemented differently than a simple 1:*
>> association. So the relationship simply conveys additional problem
>> space importance of the relationship for model comprehensibility.
>>
>> Composition: a stronger form of aggregation where the whole/part
>> relationship also implies coexistence (i.e., the whole and parts live
>> and die together).
>>
>>
>
>
> Thats interesting- It didn't know there was a distinction.

Actually, it used to be much clearer in UML in previous versions but in
v1.4 they "fixed" the definitions and made them more ambiguous. I was
also imprecise; the whole is responsible for the "disposition" of the
parts and their lifecycles are "tied together".

>
> If you have something where you can add of subtract parts after creation
> is it still considered a composition if the composite is destroyed or
> 'invalid' when it contains no parts?

An interesting question. I think UML is vague on whether the part side
can be conditional. There is a view (below) that would allow parts to
be transferred from one whole instance to another. That implies the
relationship could be conditional.

FWIW, I prefer the more stringent interpretation that the whole would be
meaningless w/o its parts and the parts are not meaningful without a
whole. That is because it is a useful constraint on referential
integrity that has well defined implications for the implementation.

Where my imprecision comes to bear is in the notion of adding and
removing parts from a whole during its life. The UML definition allows
that so long as the parts are created as part of a whole and are deleted
by the whole when they were removed.

[UML still emphasizes that whole and part lifecycles are tied together
in Composition. What it is now vague about is whether a whole can
delegate responsibility for the part disposition to another whole so
that the lifecycles are not tied to specific instances. That doesn't
make much sense to me either semantically for the notion of whole/part
or as a specification for referential integrity. But some people like
that view.]

>
>
> So maybe you had a Airplane class. It Has Missile objects on creation
> but the missiles can be subtracted. It also contains Wing Objects and
> there alway must be two of them. Some objects are required but some
> aren't. There is no method that removes wings.
>
> It it a composite or just an aggregate?

Because I prefer the strict interpretation, I would say missiles are an
Aggregation while Wings are a Composition.

Q

unread,
Feb 11, 2003, 4:39:48 PM2/11/03
to
"Daniel T." <postm...@earthlink.net> wrote in message
news:postmaster-1D7B5...@nnrp05.earthlink.net...

> > In double-entry accounting, an entry should not exist without an
account.
> > Futhermore, it should only be associated with one account. It is
important
> > [in UML] that the collection of entries that an account holds is shown
as a
> > Composition. The implementer will then ensure that an entry cannot be
> > created without being associated with an account, and that it will be
> > deleted if the account is deleted.
>
> 1 *
> [Account]-------[Entry]
>
> Represents the above requirement just fine. No need for a composition
> relationship here... Come to think of it, aren't all entries associated
> with two accounts (the account where the money is being taken out, and
> the account in which it is being added?)

1 * is not the contract.

Daniel T.

unread,
Feb 11, 2003, 9:00:55 PM2/11/03
to
"Q" <nos...@nospam.net> wrote:

> "Daniel T." <postm...@earthlink.net> wrote:
>
> > > In double-entry accounting, an entry should not exist without an
> > > account.
> > > Futhermore, it should only be associated with one account. It is
> > > important
> > > [in UML] that the collection of entries that an account holds is shown
> > > as a
> > > Composition. The implementer will then ensure that an entry cannot be
> > > created without being associated with an account, and that it will be
> > > deleted if the account is deleted.
> >
> > 1 *
> > [Account]-------[Entry]
> >
> > Represents the above requirement just fine. No need for a composition
> > relationship here... Come to think of it, aren't all entries associated
> > with two accounts (the account where the money is being taken out, and
> > the account in which it is being added?)
>
> 1 * is not the contract.

Maybe I misunderstood the contract? You wrote, that E should allways be
associated with one and only one A, and by your "collection of entries"
comment, I presumed that any one A, may be associated with many E's. Is
this correct? How is my diagram inaccurate.

Universe

unread,
Feb 11, 2003, 9:24:04 PM2/11/03
to
H. S. Lahman wrote:

> An interesting question. I think UML is vague on whether the part side
> can be conditional. There is a view (below) that would allow parts to
> be transferred from one whole instance to another. That implies the
> relationship could be conditional.

> FWIW, I prefer the more stringent interpretation that the whole would be
> meaningless w/o its parts and the parts are not meaningful without a
> whole. That is because it is a useful constraint on referential
> integrity that has well defined implications for the implementation.

Why can't a part be considered a whole in its own right at some time or
other?

Elliott
--
http://www.radix.net/~universe ~*~ Enjoy! ~*~
Hail OO Modelling! * Hail the Wireless Web!
@Elliott 2003 my comments ~ newsgroups+bitnet OK

Q

unread,
Feb 12, 2003, 7:24:58 AM2/12/03
to
"Daniel T." <postm...@earthlink.net> wrote in message
news:postmaster-C517F...@nnrp05.earthlink.net...

Your diagram is fine but does not represent the contract. It is short of an
important detail that the composite diamond makes certain: an Entry can only
exist whilst its Account exists. Your diagram does not make this obvious.
The composite diamond does, the aggregation diamond does not.

Q

unread,
Feb 12, 2003, 7:28:54 AM2/12/03
to
"Daniel T." <postm...@earthlink.net> wrote in message
news:postmaster-1D7B5...@nnrp05.earthlink.net...

> 1 *
> [Account]-------[Entry]
>
> Represents the above requirement just fine. No need for a composition
> relationship here... Come to think of it, aren't all entries associated
> with two accounts (the account where the money is being taken out, and
> the account in which it is being added?)

You are evidently not an accountant DT. What you are describing is a
transaction.

Daniel T.

unread,
Feb 12, 2003, 8:36:58 AM2/12/03
to
"Q" <nos...@nospam.net> wrote:

> "Daniel T." <postm...@earthlink.net> wrote
>


> > 1 *
> > [Account]-------[Entry]
> >
> > Represents the above requirement just fine. No need for a composition
> > relationship here... Come to think of it, aren't all entries associated
> > with two accounts (the account where the money is being taken out, and
> > the account in which it is being added?)
>
> You are evidently not an accountant DT. What you are describing is a
> transaction.

Obviously the problem domain is getting in the way of the discussion. My
point is, at the design level, there is no difference between:

*
[A]<#>----->[B]

and

*
[A]<>------>[B]

The only extra information in the former diagram, is that if the program
is being written in a non-GC language, the A object must delete the B
object when it is itself deleted. Since this requirement obviously
doesn't apply to all systems (only non-GC systems) it is an
implementation detail, not a design issue.

Also,

*
[A]<>---->[B]

and

1 *
[A]------>[B]

Are exactly equivalent. The former diagram tells us there are no object
cycles, but in the context, there can be no object cycles anyway, so the
diamond is superfluous.

The only place the aggregation symbol has any meaning is in cases like:

[A]<---+
A |
| |
[B]<>--+

Here because of the diamond, we know that although B's use an A, a B
will never use itself.

Daniel T.

unread,
Feb 12, 2003, 8:45:00 AM2/12/03
to
"Q" <nos...@nospam.net> wrote:

> "Daniel T." <postm...@earthlink.net> wrote:
>
> > "Q" <nos...@nospam.net> wrote:
> >
> > > "Daniel T." <postm...@earthlink.net> wrote:
> > >
> > > > > In double-entry accounting, an entry should not exist without an
> > > > > account.
> > > > > Futhermore, it should only be associated with one account. It is
> > > > > important
> > > > > [in UML] that the collection of entries that an account holds is
> > > > > shown
> > > > > as a
> > > > > Composition. The implementer will then ensure that an entry cannot
> > > > > be
> > > > > created without being associated with an account, and that it will
> > > > > be
> > > > > deleted if the account is deleted.
> > > >
> > > > 1 *
> > > > [Account]-------[Entry]
> > > >
> > > > Represents the above requirement just fine. No need for a composition
> > > > relationship here... Come to think of it, aren't all entries
> > > > associated
> > > > with two accounts (the account where the money is being taken out, and
> > > > the account in which it is being added?)
> > >
> > > 1 * is not the contract.
> >

> > Maybe I misunderstood the contract? You wrote, that E should always be


> > associated with one and only one A, and by your "collection of entries"
> > comment, I presumed that any one A, may be associated with many E's. Is
> > this correct? How is my diagram inaccurate.
>
> Your diagram is fine but does not represent the contract. It is short of an
> important detail that the composite diamond makes certain: an Entry can only
> exist whilst its Account exists. Your diagram does not make this obvious.
> The composite diamond does, the aggregation diamond does not.

My diagram shows that an entry must be associated with an account. Now
you tell me, if no accounts exists, and an entry must be associated with
an account, how can an entry possibly exist?

It's not the composition diamond that makes your requirement certain, it
is the "1" on the Account side of the association that makes your
requirement certain...

Q

unread,
Feb 12, 2003, 12:37:31 PM2/12/03
to
"Daniel T." <postm...@earthlink.net> wrote in message
news:postmaster-5744E...@nnrp05.earthlink.net...

> "Q" <nos...@nospam.net> wrote:
>
> > "Daniel T." <postm...@earthlink.net> wrote
> >
> > > 1 *
> > > [Account]-------[Entry]
> > >
> > > Represents the above requirement just fine. No need for a composition
> > > relationship here... Come to think of it, aren't all entries
associated
> > > with two accounts (the account where the money is being taken out, and
> > > the account in which it is being added?)
> >
> > You are evidently not an accountant DT. What you are describing is a
> > transaction.
>
> Obviously the problem domain is getting in the way of the discussion. My
> point is, at the design level, there is no difference between:

I would have thought, in this case, the problem domain is the discussion.
Without it, there is no point.

Sure. But...the composite diamond ensures no ambiguity. If someone else
works on the design, and they decide to use Entries somewhere else or in
some other way, to me at least, that filled in diamond says 'an Account is a
collection of Entries'. The Entry class defines an Account. Don't use
Entries anywhere else without talking to the chief architect for his/her
reasons.

Maybe I am wrong and it doesn't matter, but if you are right, and it really
is pointless, then why is it part of the UML? They had a long time and many
choices to bring all the notations together before ratifying it. Maybe it
was some dickhead like me who insisted on it =8-)

H. S. Lahman

unread,
Feb 12, 2003, 2:14:32 PM2/12/03
to
Responding to Daniel T....

> *
> [A]<#>----->[B]
>
> and
>
> *
> [A]<>------>[B]
>
> The only extra information in the former diagram, is that if the program
> is being written in a non-GC language, the A object must delete the B
> object when it is itself deleted. Since this requirement obviously
> doesn't apply to all systems (only non-GC systems) it is an
> implementation detail, not a design issue.

A quibble, but I think it does apply to GC languages, at least
indirectly. In a GC language one "deletes" A by making it unreachable.
That includes directly or through B. So if A being unreachable is
important one must also make B unreachable _at the same time_ as one
makes A unreachable.

H. S. Lahman

unread,
Feb 12, 2003, 2:30:50 PM2/12/03
to
Responding to Coates...

>>FWIW, I prefer the more stringent interpretation that the whole would be
>>meaningless w/o its parts and the parts are not meaningful without a
>>whole. That is because it is a useful constraint on referential
>>integrity that has well defined implications for the implementation.
>
>
> Why can't a part be considered a whole in its own right at some time or
> other?

It can be.

* *
[A]<#>-------- [B]<#>---------- [C]

is fine. It simply means that C's life cycle is indirectly tied to A's
life cycle.

However, if you mean that it can exist alone outside the whole/part
context, then I would say No. An example might be wheels on an auto
assembly line. The wheels exist in inventory, etc. before assembly but
once assembled they can be viewed as part of a Car. If the application
only deals with the assembled Car, the other views are not relevant and
composition would be appropriate. OTOH, if the application must deal
with both views as part of the assembly process, then aggregation might
be a better choice. IOW, it depends on what is important to abstract
from the problem space for the problem in hand.

Of course, one way to capture both views accurately is:

Wheel
A
|
+------+--------+
| | *
Stocked Assembled <#>----------- Car
| 1 | 1
| drawn from | transfers to
+---------------+

Daniel T.

unread,
Feb 12, 2003, 3:00:26 PM2/12/03
to
"Q" <nos...@nospam.net> wrote:

> "Daniel T." <postm...@earthlink.net> wrote in message

That is something we have discussed on this NG many times... It seems
that the consensus is that they were trying to be all things to all
people. The composition relationship was a nod to venders who wanted to
market CASE tools that translated to C++. In C++ programming that solid
diamond has a lot of meaning, hence the reason I said it is an
implementation issue.

Some here do use UML as a programming language, I don't think it's all
that good an idea. If you want a graphical programming language fine,
but UML isn't good for it IMO. Too unwieldy, and too many ambiguities.

Daniel T.

unread,
Feb 12, 2003, 4:21:33 PM2/12/03
to
"H. S. Lahman" <h.la...@verizon.net> wrote:

> Responding to Daniel T....
>
> > *
> > [A]<#>----->[B]
> >
> > and
> >
> > *
> > [A]<>------>[B]
> >
> > The only extra information in the former diagram, is that if the program
> > is being written in a non-GC language, the A object must delete the B
> > object when it is itself deleted. Since this requirement obviously
> > doesn't apply to all systems (only non-GC systems) it is an
> > implementation detail, not a design issue.
>
> A quibble, but I think it does apply to GC languages, at least
> indirectly. In a GC language one "deletes" A by making it unreachable.
> That includes directly or through B. So if A being unreachable is
> important one must also make B unreachable _at the same time_ as one
> makes A unreachable.

This is not something that programmers in GC languages need worry about.
When they are done with an object, they release the reference. It
becomes unreachable when all holders have released it.

Maybe an example will be a good idea here:

[A]<#>---->[B]<-----[C]

Java

class B { }

class A {
public B b;
public A() { b = new B(); }
}

class C {
public B b;
}

The code is a perfectly valid translation of the UML above it. Now,
assuming a method like:

public void foo( C c ) {
A a = new A();
c.b = a.b;
}

(Which is also perfectly acceptable according to the UML above,) how are
we to ensure that A can make the B object "unreachable"? Answer, it
can't.

In a GC language, the only way to ensure that the B object is
unreachable at the same time the A object becomes unreachable, is by
ensuring that the A object is the only object holding a reference to the
B object. And the only way to do that is to give the A object exclusive
access to the B object.

In a non-GC language, one can delete the B object when the A object gets
deleted, but if any other object is holding a reference to the B object
at that time, it will be left with a dangling pointer, one of the most
dreaded bugs in C++. The only way to guarantee that this won't happen,
is again to ensure that the A object in question has exclusive use of
the B object.

Which is why I think the composition relationship *should* mean
exclusive access, even though it officially doesn't.

Uncle Bob (Robert C. Martin)

unread,
Feb 12, 2003, 6:04:39 PM2/12/03
to
"Kovanan" <som...@microsoft.com> might (or might not) have written
this on (or about) Mon, 10 Feb 2003 04:47:13 GMT, :

>I am not very clear on when I should use dependency, when association, and
>when aggregation. Could you tell me what the rule is for deciding which one
>of them is to be used when?

Use association whenever one class needs to send messages to another.

Don't use aggregation -- nobody agrees on what it means.

Use dependency when one class depends upon another because of a method
argument.

Use composition when one class manages the lifetime (i.e. destruction)
of another.

That's about it.

For more on this see: "UML for Java Programmers"
You can get the manuscript at http://www.objectmentor.com/UMLFJP


Robert C. Martin | "Uncle Bob"
Object Mentor Inc.| unclebob @ objectmentor . com
PO Box 5757 | Tel: (800) 338-6716
565 Lakeview Pkwy | Fax: (847) 573-1658 | www.objectmentor.com
Suite 135 | | www.XProgramming.com
Vernon Hills, IL, | Training and Mentoring | www.junit.org
60061 | OO, XP, Java, C++, Python |

"...a member of my local hiking club is a
nudist. I once asked him if he ever hiked in the nude. He responded
that he was a nudist, he wasn't nuts."
-- Daniel Parker

H. S. Lahman

unread,
Feb 13, 2003, 4:31:08 PM2/13/03
to
Responding to Daniel T....

> This is not something that programmers in GC languages need worry about.
> When they are done with an object, they release the reference. It
> becomes unreachable when all holders have released it.
>
> Maybe an example will be a good idea here:
>
> [A]<#>---->[B]<-----[C]
>
> Java
>
> class B { }
>
> class A {
> public B b;
> public A() { b = new B(); }
> }
>
> class C {
> public B b;
> }
>
> The code is a perfectly valid translation of the UML above it. Now,
> assuming a method like:
>
> public void foo( C c ) {
> A a = new A();
> c.b = a.b;
> }
>
> (Which is also perfectly acceptable according to the UML above,) how are
> we to ensure that A can make the B object "unreachable"? Answer, it
> can't.

One can do that by clearing the c.b reference. But the real issue is
for relationships that are bi-directional. Now we have:

class A {
public B b;
}

class B {
public A a;
}

class C {
public B b;
}

Now we have to instantiate A and B in a single method to ensure
referential integrity:

public void foo (C c)


A a = new A()

B b = new B()
a.b = b;
b.a = a;
c.b = b;
}

Case 1: A must be unreachable subsequently. One must clear all b.a
references to this 'a' and all other references to 'a'. (For my view of
composition, one would actually have to clear the c.b references to
those Bs since the Bs should also be unreachable.)

Case 2: B must be unreachable subsequently. One must clear the relevant
a.b and c.b references.

Case 3: C must be unreachable subsequently. One must clear all other
references of 'c'.

If the developer does not do that, then...

>
> In a GC language, the only way to ensure that the B object is
> unreachable at the same time the A object becomes unreachable, is by
> ensuring that the A object is the only object holding a reference to the
> B object. And the only way to do that is to give the A object exclusive
> access to the B object.
>
> In a non-GC language, one can delete the B object when the A object gets
> deleted, but if any other object is holding a reference to the B object
> at that time, it will be left with a dangling pointer, one of the most
> dreaded bugs in C++. The only way to guarantee that this won't happen,
> is again to ensure that the A object in question has exclusive use of
> the B object.

... I think both cases are program bugs. It is up to the developer to
ensure referential integrity. In the GC case the developer must ensure
that B cannot be reached from C by clearing the c.b reference. (The C/B
relationship must be conditional if c.b is assigned in a different scope
than 'c' was created.)

Daniel T.

unread,
Feb 13, 2003, 11:53:50 PM2/13/03
to
In article <3E4C0E...@verizon.net>,

"H. S. Lahman" <h.la...@verizon.net> wrote:

> Responding to Daniel T....
>
> > This is not something that programmers in GC languages need worry about.
> > When they are done with an object, they release the reference. It
> > becomes unreachable when all holders have released it.
> >
> > Maybe an example will be a good idea here:
> >
> > [A]<#>---->[B]<-----[C]
> >
> > Java
> >
> > class B { }
> >
> > class A {
> > public B b;
> > public A() { b = new B(); }
> > }
> >
> > class C {
> > public B b;
> > }
> >
> > The code is a perfectly valid translation of the UML above it. Now,
> > assuming a method like:
> >
> > public void foo( C c ) {
> > A a = new A();
> > c.b = a.b;
> > }
> >
> > (Which is also perfectly acceptable according to the UML above,) how are
> > we to ensure that A can make the B object "unreachable"? Answer, it
> > can't.
>
> One can do that by clearing the c.b reference.

Ah, but then A doesn't have lifetime control and that is the point of
the solid diamond. In order for A to have lifetime control, no other
object can be allowed to hold a reference to the B object, even for the
space of one method. IE A must have exclusive rights to the B object.

We differ in opinion on where the bug lies. I say the bug is in the fact
that the design requires A to have lifetime control of the B object, but
also allows other objects to hold references to the very same B object.
A *cannot* have lifetime control of an object that other objects are
using. This entire problem goes away if we assume composition to mean
exclusive access. Then the composing class can actually control the
lifetime of the composite safely.

H. S. Lahman

unread,
Feb 14, 2003, 1:28:45 PM2/14/03
to
Responding to Daniel T....

>>>(Which is also perfectly acceptable according to the UML above,) how are
>>>we to ensure that A can make the B object "unreachable"? Answer, it
>>>can't.
>>
>>One can do that by clearing the c.b reference.
>
>
> Ah, but then A doesn't have lifetime control and that is the point of
> the solid diamond. In order for A to have lifetime control, no other
> object can be allowed to hold a reference to the B object, even for the
> space of one method. IE A must have exclusive rights to the B object.

But if A clears c.b, then A does have lifetime control. I am simply
saying that in the strict interpretation A *must* clear c.b or there is
a software bug because the GC code has not properly handled the implied
referential integrity around the life cycle constraint.

>>>In a GC language, the only way to ensure that the B object is
>>>unreachable at the same time the A object becomes unreachable, is by
>>>ensuring that the A object is the only object holding a reference to the
>>>B object. And the only way to do that is to give the A object exclusive
>>>access to the B object.
>>>
>>>In a non-GC language, one can delete the B object when the A object gets
>>>deleted, but if any other object is holding a reference to the B object
>>>at that time, it will be left with a dangling pointer, one of the most
>>>dreaded bugs in C++. The only way to guarantee that this won't happen,
>>>is again to ensure that the A object in question has exclusive use of
>>>the B object.
>>
>>... I think both cases are program bugs. It is up to the developer to
>>ensure referential integrity. In the GC case the developer must ensure
>>that B cannot be reached from C by clearing the c.b reference. (The C/B
>>relationship must be conditional if c.b is assigned in a different scope
>>than 'c' was created.)
>
>
> We differ in opinion on where the bug lies. I say the bug is in the fact
> that the design requires A to have lifetime control of the B object, but
> also allows other objects to hold references to the very same B object.
> A *cannot* have lifetime control of an object that other objects are
> using. This entire problem goes away if we assume composition to mean
> exclusive access. Then the composing class can actually control the
> lifetime of the composite safely.

I think it would be a modeling error only if the C/B relationship were
unconditional, which is why I put in the caveat in the last sentence.
If the relationship is conditional, then c.b can be cleared by A at the
time that B must be made unreachable.

[Even if C/B is unconditional, one could still clear all other
references to C to make B unreachable. Of course this just moves the
conditionality back from C/B.]

If one has the appropriate conditional relationships somewhere in the
model, then the model is viable and it is up to the developer to ensure
referential integrity when B must be made unreachable. That requires at
least as much work in a GC language as in a non-GC language, which was
my point. (I would argue the possible errors are even more subtle in a
GC language than in a non-GC language.)

Q

unread,
Feb 15, 2003, 9:13:19 AM2/15/03
to
"Daniel T." <postm...@earthlink.net> wrote in message
news:postmaster-84A50...@nnrp05.earthlink.net...

> That is something we have discussed on this NG many times... It seems
> that the consensus is that they were trying to be all things to all
> people. The composition relationship was a nod to venders who wanted to
> market CASE tools that translated to C++. In C++ programming that solid
> diamond has a lot of meaning, hence the reason I said it is an
> implementation issue.

Sorry, DT, but I just read the above again. You say, at design level the
solid diamond is not relevant because it is an implementation issue. Then
above you say in C++ 'that solid diamond has a lot of meaning'.

If you draw a UML diagram at design level using aggregation instead of
composition. Then you give it to some subordinate to produce an
'implementation level' diagram, will that person think to change the agg. to
a solid diamond just because it will be implemented in C++. No, and why
should he, so the ambiguity you left by being so picky about a detail flows
down through your development group into code that may have flaws, and,
referring to my own specialist domain, design flaws.

> Some here do use UML as a programming language, I don't think it's all
> that good an idea. If you want a graphical programming language fine,
> but UML isn't good for it IMO. Too unwieldy, and too many ambiguities.

This is pure FUD. You don't like CASE tools, therefore why should anyone
else find them useful.

Daniel T.

unread,
Feb 16, 2003, 11:02:19 AM2/16/03
to
"Q" <nos...@nospam.net> wrote:

> "Daniel T." <postm...@earthlink.net> wrote
>


> > That is something we have discussed on this NG many times... It seems
> > that the consensus is that they were trying to be all things to all
> > people. The composition relationship was a nod to venders who wanted to
> > market CASE tools that translated to C++. In C++ programming that solid
> > diamond has a lot of meaning, hence the reason I said it is an
> > implementation issue.
>
> Sorry, DT, but I just read the above again. You say, at design level the
> solid diamond is not relevant because it is an implementation issue. Then
> above you say in C++ 'that solid diamond has a lot of meaning'.
>
> If you draw a UML diagram at design level using aggregation instead of
> composition. Then you give it to some subordinate to produce an
> 'implementation level' diagram, will that person think to change the agg. to

> a solid diamond just because it will be implemented in C++? No, and why


> should he, so the ambiguity you left by being so picky about a detail flows
> down through your development group into code that may have flaws, and,
> referring to my own specialist domain, design flaws.

I think that any C++ programmer worth his salt worries about ownership
issues. He manually tracks how many objects are holding a reference to a
given object and ensures that the last object to hold the reference
deletes the given object. (Or he creates "smart pointer" classes to do
the tracking for him.) He does this *regardless* of what any design doc
might say.

C++ is, I believe, the only OO language where the programmer has to deal
with this issue. Other OO languages either have garbage collection, or
at least reference counting. Any artifact in UML that is only pertinent
if one is using C++ is an implementation issue.

Just to make sure I answered your question directly. I think that if you
give a UML diagram to a C++ programmer and ask him to implement it, he
will make sure that all objects have definite ownership semantics and he
will make sure that they all get deleted when no longer needed... no
matter what the UML says about the issue. If he doesn't do this, then he
can't be trusted to write code without supervision.


> > Some here do use UML as a programming language, I don't think it's all
> > that good an idea. If you want a graphical programming language fine,
> > but UML isn't good for it IMO. Too unwieldy, and too many ambiguities.
>
> This is pure FUD. You don't like CASE tools, therefore why should anyone
> else find them useful.

I was careful to make sure I put an "IMO" in the above. I did that for a
reason...

Q

unread,
Feb 17, 2003, 9:14:10 AM2/17/03
to
"Daniel T." <postm...@earthlink.net> wrote in message
news:postmaster-2B15D...@nnrp02.earthlink.net...

The composition and aggregation symbols in UML are important IMO. End of
discussion then.

0 new messages