Association Vs. Aggregation - Is there a difference.

976 views
Skip to first unread message

mar...@ratio.co.uk

unread,
May 25, 1998, 3:00:00 AM5/25/98
to

Every time I look at a different project, I see aggregation (by reference)
being used in a different way, often with no discernable difference from
mandatory association.

My question: is there any semantic difference (i.e. a difference that would
lead us to implmenting them in different ways) between

mandatory association (e.g. mandatory 1 to ... whatever) and
aggregation (of the hollow diamond sort - i.e. I'm not concerned with
the containment by value type of aggregation, which clearly does have
a different implementation from association).

For the purposes of this question, vague descriptions of "is-a-part-of"
relationships are not what I'm after - I'm after a measurable difference
in the way we'd implement the two options).

I've considered the "linked lifetimes" option: you must delete the "part-of"
object when the object it is part of is deleted. Again, there seems to be
no difference between this an mandatory association (if you delete an
object to which there is a mandatory to-one relationship, you have to
delete the related objects to maintain the systems integrity).

The only possibility that seemed to hold some hope was that an object can
only be aggregated to one other object (i.e. it can't be "part-of" two
objects"). But this seems to have been thrown out in UML by the fact that,
for example, it is possible for a "player" to be aggregated to more than
one "team"!

My second question is: if there isn't a differnce, isn't it about time
aggregation by value was removed from UML?

Yours in search of enlightenment,

Mark Collins-Cope
Ratio Group Ltd.
+44 181 579 7900
See www.ratio.co.uk

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading

Robert Martin

unread,
May 25, 1998, 3:00:00 AM5/25/98
to

UML does not contain the concept of "Aggregation by Value" anymore.
It was discarded in UML 1.1.

UML now has:

* Association, represents the ability of one instance to send
a message to another instance. This is typically implemented with
a pointer or reference instance variable, although it might also
be implemented as a method argument, or the creation of a local
variable.

* Aggregation, which is the typical whole/part relationship. This
is exactly the same as an association with the exception that
instances cannot have cyclic aggregation relationships (i.e. a part
cannot contain its whole).

* Composition, which is exactly like Aggregation except that the
lifetime of the 'part' is controlled by the 'whole'. This control
may be direct or transitive. That is, the 'whole' may take direct
responsibility for creating or destroying the 'part', or it may
accept an already created part, and later pass it on to some
other whole that assumes responsibility for it.

**We are looking for good engineers, See our website
**for more information.

Robert C. Martin | Design Consulting | Training courses offered:
Object Mentor | rma...@oma.com | Object Oriented Design
14619 N Somerset Cr | Tel: (800) 338-6716 | C++
Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com

"One of the great commandments of science is:
'Mistrust arguments from authority.'" -- Carl Sagan

mar...@ratio.co.uk wrote in message <6kcimm$p93$1...@nnrp1.dejanews.com>...

mar...@ratio.co.uk

unread,
May 26, 1998, 3:00:00 AM5/26/98
to

Thanks for the response. Wouild it be possible you could expand your
answer with a couple of examples (esp. with respect to implementation)

Mark.

In article <6kdgh2$h1v$1...@hirame.wwa.com>,


"Robert Martin" <rma...@oma.com> wrote:
>
> UML does not contain the concept of "Aggregation by Value" anymore.
> It was discarded in UML 1.1.
>
> UML now has:
>
> * Association, represents the ability of one instance to send
> a message to another instance. This is typically implemented with
> a pointer or reference instance variable, although it might also
> be implemented as a method argument, or the creation of a local
> variable.

Happy with this.

> * Aggregation, which is the typical whole/part relationship. This
> is exactly the same as an association with the exception that
> instances cannot have cyclic aggregation relationships (i.e. a part
> cannot contain its whole).

Unclear what you mean by the last part of this.

> * Composition, which is exactly like Aggregation except that the
> lifetime of the 'part' is controlled by the 'whole'. This control
> may be direct or transitive. That is, the 'whole' may take direct
> responsibility for creating or destroying the 'part', or it may
> accept an already created part, and later pass it on to some
> other whole that assumes responsibility for it.

In implementation terms, does this in general mean containment of the
aggregated object by value (in C++ day).

Robert Martin

unread,
May 26, 1998, 3:00:00 AM5/26/98
to

mar...@ratio.co.uk wrote in message <6ke3sn$66o$1...@nnrp1.dejanews.com>...


>Thanks for the response. Wouild it be possible you could expand your
>answer with a couple of examples (esp. with respect to implementation)

OK, they are included below.

>In article <6kdgh2$h1v$1...@hirame.wwa.com>,
> "Robert Martin" <rma...@oma.com> wrote:
>>
>> UML does not contain the concept of "Aggregation by Value" anymore.
>> It was discarded in UML 1.1.
>>
>> UML now has:
>>
>> * Association, represents the ability of one instance to send
>> a message to another instance. This is typically implemented with
>> a pointer or reference instance variable, although it might also
>> be implemented as a method argument, or the creation of a local
>> variable.
>Happy with this.

An example of association:

class A
{
private:
B* itsB; |A|----------->|B|
};

>
>> * Aggregation, which is the typical whole/part relationship. This
>> is exactly the same as an association with the exception that
>> instances cannot have cyclic aggregation relationships (i.e. a part
>> cannot contain its whole).
>Unclear what you mean by the last part of this.

It is the difference between a tree and a graph.

|Node|<>-------->|Node|

class Node
{
private:
vector<Node*> itsNodes;
};

The fact that this is aggregation means that the instances of Node
cannot form a cycle. Thus, this is a Tree of Nodes not a graph of
Nodes.


>
>> * Composition, which is exactly like Aggregation except that the
>> lifetime of the 'part' is controlled by the 'whole'. This control
>> may be direct or transitive. That is, the 'whole' may take direct
>> responsibility for creating or destroying the 'part', or it may
>> accept an already created part, and later pass it on to some
>> other whole that assumes responsibility for it.
>In implementation terms, does this in general mean containment of the
>aggregated object by value (in C++ day).
>

No, not necessarily. It can also mean containment by reference so
long as lifetime is controlled:

|Car><#>-------->|Carburetor|

class Car
{
public:
virtual ~Car() {delete itsCarb;}
private:
Carburetor* itsCarb
};

Roger L. Cauvin

unread,
May 26, 1998, 3:00:00 AM5/26/98
to

How about dependency? Does UML still have it?


Robert Martin

unread,
May 26, 1998, 3:00:00 AM5/26/98
to

Roger L. Cauvin wrote in message
<19204E9D46CCD11194E...@dal-01-msg.objectspace.com>...


>How about dependency? Does UML still have it?
>

Yes, and it's still the dashed arrow.

|A|- - - - ->|B|

This means that A somehow depends upon B. That is, in order for A to
function, B
must be present. This might be a compile time dependency, a link time
dependency,
or a runtime dependency.

Tim Ottinger

unread,
May 26, 1998, 3:00:00 AM5/26/98
to


Robert Martin wrote:

> * Association, represents the ability of one instance to send
> a message to another instance. This is typically implemented with
> a pointer or reference instance variable, although it might also
> be implemented as a method argument, or the creation of a local
> variable.

Or when A can send a message to B because B is global?


Robert Martin

unread,
May 26, 1998, 3:00:00 AM5/26/98
to

Tim Ottinger wrote in message <356B3B80...@oma.com>...

Well, I think we could use a <<global>> stereotype for that.

|A|---------------->|B|
<<global>>

**We are looking for good engineers, See our website
**for more information.

Robert C. Martin | Design Consulting | Training courses offered:

pj...@firstam.com

unread,
May 29, 1998, 3:00:00 AM5/29/98
to

> must be present. This might be a compile time dependency, a link time
> dependency,
> or a runtime dependency.
>

what is a runtime dependency
Thanks.

> Robert C. Martin | Design Consulting | Training courses offered:
> Object Mentor | rma...@oma.com | Object Oriented Design
> 14619 N Somerset Cr | Tel: (800) 338-6716 | C++
> Green Oaks IL 60048 | Fax: (847) 918-1023 | http://www.oma.com
>
> "One of the great commandments of science is:
> 'Mistrust arguments from authority.'" -- Carl Sagan
>
>

pj...@firstam.com

unread,
May 29, 1998, 3:00:00 AM5/29/98
to


> >> * Composition, which is exactly like Aggregation except that the
> >> lifetime of the 'part' is controlled by the 'whole'. This control
> >> may be direct or transitive. That is, the 'whole' may take direct
> >> responsibility for creating or destroying the 'part', or it may
> >> accept an already created part, and later pass it on to some
> >> other whole that assumes responsibility for it.

Could you explain with example,if possible, how part can be controlled
transitively by the whole when is accepts an already created part.

Thanks

Robert Martin

unread,
May 29, 1998, 3:00:00 AM5/29/98
to

pj...@firstam.com wrote in message <6kngd9$k5p$1...@nnrp1.dejanews.com>...


>
>what is a runtime dependency
>Thanks.


Some software entity that must be present at runtime, but that the
source code knows nothing about. e.g. io drivers, objects that are
dynamically created from strings, etc.

**We are looking for good engineers, See our website
**for more information.

Robert C. Martin | Design Consulting | Training courses offered:

Robert Martin

unread,
May 29, 1998, 3:00:00 AM5/29/98
to

pj...@firstam.com wrote in message <6kngr3$l2q$1...@nnrp1.dejanews.com>...


>
>
>> >> * Composition, which is exactly like Aggregation except that the
>> >> lifetime of the 'part' is controlled by the 'whole'. This control
>> >> may be direct or transitive. That is, the 'whole' may take direct
>> >> responsibility for creating or destroying the 'part', or it may
>> >> accept an already created part, and later pass it on to some
>> >> other whole that assumes responsibility for it.
>
>Could you explain with example,if possible, how part can be controlled
>transitively by the whole when is accepts an already created part.


class Whole
{
public:
Whole() : itsPart(0) {}
virtual ~Whole() {delete itsPart;}

void Accept(Part* p)
{
delete itsPart;
itsPart = p;
}

Part* Release()
{
Part* p = itsPart;
itsPart = 0;
return p;
}
private:
Part* itsPart;
};

This class can accept a part, and can release a part too. But if
it is destroyed, then any part it is currently holding will be
destroyed too.

Ell

unread,
May 30, 1998, 3:00:00 AM5/30/98
to

"Robert Martin" <rma...@oma.com> wrote:

>pj...@firstam.com wrote in message <6kngd9$k5p$1...@nnrp1.dejanews.com>...
>>
>>what is a runtime dependency
>>Thanks.

>Some software entity that must be present at runtime,

Agreed, though I think there are other qualifications, and conditions:
1) The same run-time dependency may or not exist at any given
time.
2) Some run-time dependencies are constant and others
intermittent.
3) Some run-time dependencies are optional and others necessary.


>but that the
>source code knows nothing about. e.g. io drivers, objects that are
>dynamically created from strings, etc.

It seems to me that given a *constant* run-time dependency it should
be fairly easy to identify how this happens by reading source code.
Not always, but often.

For the other types of run-time dependencies, the *potential* for a
run-time dependency to occur *must* exist in one or more places *in*
the *source code*. That specific code may be more, or less difficult
to identify. If the *potential* for run-time dependency is not
expressed in one, or more specific places in the source code, how can
it occur?

Elliott
--
:=***=: Objective * Pre-code Modelling * Holistic :=***=:
Hallmarks of the best SW Engineering
"The domain object model is the foundation of OOD."
Check out SW Modeller vs SW Craftite Central : www.access.digex.net/~ell
Copyright 1998 Elliott. exclusive of others' writing. may be copied
without permission only in the comp.* usenet and bitnet groups.

dani...@gte.net

unread,
May 30, 1998, 3:00:00 AM5/30/98
to

mar...@ratio.co.uk wrote:

>My question: is there any semantic difference (i.e. a difference that would
>lead us to implmenting them in different ways) between
>
>mandatory association (e.g. mandatory 1 to ... whatever) and
>aggregation (of the hollow diamond sort - i.e. I'm not concerned with
>the containment by value type of aggregation, which clearly does have
>a different implementation from association).

How about the transitive nature of association?

If A is associated with B
and B is associated with C,
then A is not necessarily associated with C.

If A is an aggregate of B
and B is an aggregate of C,
then A must be an aggregate of C.

Seems to me that would produce difference in the implementation... But I'm
just a newbie. :-) Am I right?

--
Daniel T.
dani...@gte.net
http://home1.gte.net/danielt3/

Robert Martin

unread,
May 30, 1998, 3:00:00 AM5/30/98
to

dani...@gte.net wrote in message <6kopnu$ofk$1...@gte2.gte.net>...


>
>How about the transitive nature of association?
>
>If A is associated with B
>and B is associated with C,
>then A is not necessarily associated with C.

>
>If A is an aggregate of B
>and B is an aggregate of C,
>then A must be an aggregate of C.

>
>Seems to me that would produce difference in the implementation... But I'm
>just a newbie. :-) Am I right?
>

Yes. The difference in implementation is the difference between
a graph and a tree.

In the simplest case:

|Node|----------->|Node| (Graph)
*


|Node|<>--------->|Node| (Tree)
*

To state this in English, a cycle of instances can be created
with associations, but not with aggregations.

Ell

unread,
May 30, 1998, 3:00:00 AM5/30/98
to

e...@access.digex.net (Ell) wrote:

>It seems to me that given a *constant* run-time dependency it should
>be fairly easy to identify how this happens by reading source code.
>Not always, but often.
>
>For the other types of run-time dependencies, the *potential* for a
>run-time dependency to occur *must* exist in one or more places *in*
>the *source code*. That specific code may be more, or less difficult
>to identify. If the *potential* for run-time dependency is not
>expressed in one, or more specific places in the source code, how can
>it occur?

In fact the *potential* run-time dependency of a client on the
concrete classes in server hierarchy headed by an abstract base class
(ABC) is "expressed" by:
1) the concrete class code showing that the concrete class
inherits from the ABC
2) the fact that a client holds a pointer to the ABC.

That pattern of code configuration "expresses" (and implies) the
*potential* run-time dependency that the client has on one of the
concrete classes derived from the ABC.

Reply all
Reply to author
Forward
0 new messages