Re: Aggregation vs composition

From: Daniel T. (postmaster_at_eathlink.net)
Date: 05/24/04


Date: Mon, 24 May 2004 01:57:58 GMT

In article <c8rde6$344$06$1@news.t-online.com>,
 Michael Rauscher <michlmann@gmx.de> wrote:

>Daniel T. schrieb:
>> In article <c8qr58$rpb$1@news1.nefonline.de>,
>> "Matthias Hofmann" <hofmann@anvil-soft.com> wrote:
>>
>>
>>>Daniel T. <postmaster@eathlink.net> schrieb in im Newsbeitrag:
>>>postmaster-41002B.22471722052004@news5.west.earthlink.net...
>>>
>>>>Again, I'm left with the feeling that no client of A should be allowed
>>>>to send a message directly to its 'b' object without A having a chance
>>>>to intercept, and possibly reinterpret that message.
>>>
>>>Then simply don't design your code in such a way. Others have already said
>>>that the UML does not prevent you from bad design.
>>
>>
>> By this comment, are you saying that allowing others to share the part
>> is "bad design"?
>
>Well, I'd say it's bad design, if one doesn't hide information when he
>would be able to.

I'm more than happy to accept that as a compromise.

>>>>No, my answer is that after the addition of that one method, CarClient's
>>>>responsibility for engine is exactly the same as Car's responsibility
>>>>for that very same engine object. Both must make sure their use of the
>>>>engine does not conflict with the other's use of that same engine,
>>>
>>>This point has nothing to do with the responsibility for the disposition of
>>>the engine.
>>
>>
>> Obviously I don't agree. Being solely responsible for ones disposition
>> includes responsibility for their attitude...
>
>That's your interpretation of "being solely responsible". UML's
>specification gives this term a more precise meaning: "that means that
>the whole is responsible for creation and destruction of the parts. In
>implementation terms, it is responsible for their memory allocation".
>Within this refinement the terms "sole" or "solely" don't appear.
>
>Does CarClient allocate memory for Car's Engine? No.
>Does CarClient free the memory for Car's Engine? No.
>Is there any other class that allocates/frees memory for Engines? No.

Say you saw code like this:

Engine* makeEngine() {
   return new Engine;
}

void destroyEngine(Engine* e) {
   delete e;
}

void func() {
   Engine* e = makeEngine();
   // do something with e
   destroyEngine( e );
}

Which of the above is responsible for an engine's memory allocation /
deallocation? Or would you say that both func and makeEngine are
responsible for allocation, both func and destroyEngine are responsible
for deallocation?

And since you brought creation into it:

class Car {
   Engine* e;
public:
   Car():e(0){}
   ~Car() { delete e; }
   void acceptEngine(Engine*& e_) { delete e; e = e_; e_ = 0; }
};

Here car doesn't create its engine, but does hide it (as best it can,)
and does delete it. Is this not Composition, simply because Car is not
"responsible for creation and destruction of the part"?

For my part, I would say that this was composition, but I would love to
hear what others think.

>>>>both must ensure that the engine's lifetime is sufficient for the other,
>>>
>>>In your own words, you are simply holding this point self-evident, which I
>>>find to be not a very convincing argument.
>>
>>
>> Surely you must agree that if either client calls delete on the engine
>> at an inappropriate time, that would be the responsibility of the client
>> that did so?
>
>Right and therefore such client would violate the semantics of composition.

So Car can "violate the semantics of composition" by deleting the object
it is solely responsible for. How can it be solely responsible yet not
be allowed to do the thing it is responsible for?

>>>>and both must ensure that Car is the last object to see the engine alive.
>>>
>>>As Car destroys Engine, it will definitely be the last one to see it alive.
>>
>> First, you don't know that Car destroys Engine, all that is known is
>> that car is calling 'delete' on engine which may, or may not deallocate
>> the memory. Second Car cannot call delete on Engine unless it knows that
>> CarClient is done using it, to do otherwise would be irresponsible.
>
>Ad "First": And? AFAIK it's delete's intension to destroy objects.

Operator delete is simply a function like any other. Although it has a
default implementation, it certainly can do otherwise. See any number of
small object allocators on the net for an example. But I have no desire
to belabor the point, I probably shouldn't have brought it up.

>Ad "Second": This has nothing to do with composition. I'd say that in
>one should never (at least with respect to software development) destroy
>objects that are "in use" - regardless of the association type. But:
>neither association type prevents one from deleting used objects.

You added the period prematurely, that should read "... neither
association type prevents one from deleting used objects in C++." You
see the association *does* prevent the deletion of used objects in every
other language that I'm aware of. IE a comment such as the one above
implies that Composition is solely for C++ and has nothing to do with OO
in general.

>Of course, you may hide parts (so part objects are used only by the
>whole) and therefore prevent the programmer technically from deleting
>used objects - because there aren't used but by the whole. But this is a
>design issue and has nothing to do with composition:

Isn't UML for design use? Shouldn't design issues be expressible in a
design language like UML?

>Compare (Organization doesn't hide departments)
>
>[Organization]<#>-----[Deparment]<-------[Person]
>
>with (Organization completely hides departments)
>
>[Organization]<#>-----[Deparment]
> /|\
> |
> [Person]
>
>Problem: The latter diagram doesn't show that a person works in a
>department.

Why not simply:

 [Organization]<>-----[Deparment]<-------[Person]

Is this diagram so incredibly distasteful?

> Now, you could add an identifier to both, Deparment and Person:
>
>+-----------+
>| Person |
>+-----------+
>|-depId:int |
>+-----------+
>
>Now, Organization can hide Department. Organization can destroy
>Department at any time - even in GC languages :-)
>
>But: Person holds a "reference" to Deparment, although there is no
>association between them.
>
>Would you now say, that
>a) Organization should delete Deparments even if there are Persons that
>hold references on the latter?

Since person has no direct link to a Department object, the only way a
message could go from Person to Department is through Organization which
would obviously have measures in place to appropriately handle the
message if the department no longer exists. Organization would not have
this option if Person had a direct link to an organization.

So, in answer to your question, I would have no problem with
Organization dropping a department even if Persons are associated with
that department in this case, because Organization can intercept any
message sends from that Person to the department. As you have already
said, Organization actually *can* "delete" departments, even in GC
languages. :-)

>b) the composition prevents from deleting Deparments that Persons are
>pointing to?
>
>Or would you now say, that it isn't a composition because Person *knows*
>about the existence of departments?

Strictly speaking, Person doesn't know about the existence of
departments, all it knows is that there are a set of methods in
Organization that require the Person to provide its 'depId'. For all
Person knows, the Organization class doesn't even exist.

I need to say though, that I dislike the design proposed. It allows a
person to change his department by simply adding to or subtracting from
an int that it holds, if Person has a link to its department object, it
can give up on its department but a person can't change departments
without consulting the Organization. In general, I would rather see the
composition relationship dropped, converted to aggregation than see the
composition relationship inappropriately maintained like this.



Relevant Pages

  • Re: Aggregation vs composition
    ... Yes, the Car cannot delete it, if you like that better. ... The only possible way for the engine to be deleted once ... Composition does not forbid sharing, as long as the part is not shared by ... Well, if that doesn't indicate sole responsibility, what else does? ...
    (comp.object)
  • Re: Aggregation vs composition
    ... > Composition is appropriate even though it requires the whole to be ... That means that no two Car objects are allowed to ... >>a pointer to the same Engine. ... The way I interpret your postings, "sole responsibility" for you means that ...
    (comp.object)
  • Re: OT. Freedom Of Speech
    ... last ditch design of pure expedience - take a very simple and quick to ... Instant jet fighter, and never mind the ... engine that was inclined to explode in bad landings in the early models. ... they couldn't go in the directions needed to sort things out. ...
    (uk.people.support.depression)
  • Re: Me P.1110 Ente Art
    ... time and reliable engine power. ... It is known the German engine jet reliability and lifetimes were going up, ... if it is a German design Eunometic will find something ... limited to a little over Mach 0.8 to Mach 0.85 while the German ...
    (rec.aviation.military)
  • Re: Google Cindy Sheehan (was: Re: Peace Mom)
    ... >>>Part of it, though, is inherent in the design and something that would ... This reduces the engine length and ... >helps you some with the vehicle profile. ... why switch propellants in an SSTO? ...
    (misc.writing)