Skip to content

Instantly share code, notes, and snippets.

@puiutucutu
Last active December 28, 2022 05:31
Show Gist options
  • Save puiutucutu/90b9f17921ab39989c54 to your computer and use it in GitHub Desktop.
Save puiutucutu/90b9f17921ab39989c54 to your computer and use it in GitHub Desktop.
<?php
/**
* Existence of Composition class requires that an external object of
* class B is passed in on construction
*
* UML Explanation - The object at this role contains the object at the opposite role.
*
* Alternatively stated, an object of class Composition cannot be created without
* an object of class B (in this case through dependency injection)
*/
class Composition {
private $internal_obj;
public function __construct(B $external_obj) {
$this->internal_obj = $external_obj; // requires an object of class B
}
}
/**
* Existence of the Aggregation class does not require the existence of B class,
* since the Aggregation class builds its own object of class B
*
* UML Explanation - Object at this role contains references to the object at the other role
*/
class Aggregation {
private $internal_obj;
public function __construct() {
$this->internal_obj = new B;
}
}
@puiutucutu
Copy link
Author

Thinking of classes in set theory, when using aggregation the subset exists independently of the set. In composition, the subset depends on the existence of the set.

Additional Details

Full Name Short Name Association Ownership Subset Requires Set
composition aggregation composition strong owns a true
basic aggregation aggregation weak has a false

UML

http://edn.embarcadero.com/article/31863
http://www.holub.com/goodies/uml/
http://msdn.microsoft.com/en-us/library/dd409437%28VS.100%29.aspx

image

@puiutucutu
Copy link
Author

Notes

http://www.holub.com/goodies/uml/#composition

Footnotes
(1) Composition vs. Aggregation:
Neither "aggregation" nor "composition" really have direct analogs in many languages (Java, for example).

An "aggregate" represents a whole that comprises various parts; so, a Committee is an aggregate of its Members. A Meeting is an aggregate of an Agenda, a Room, and the Attendees. At implementation time, this relationship is not containment. (A meeting does not contain a room.) Similarly, the parts of the aggregate might be doing other things elsewhere in the program, so they might be referenced by several objects. In other words, There's no implementation-level difference between aggregation and a simple "uses" relationship (an "association" line with no diamonds on it at all). In both cases an object has references to other objects. Though there's no implementation difference, it's definitely worth capturing the relationship in the UML, both because it helps you understand the domain model better, and because there are subtle implementation issues. I might allow tighter coupling relationships in an aggregation than I would with a simple "uses," for example.

Composition involves even tighter coupling than aggregation, and definitely involves containment. The basic requirement is that, if a class of objects (call it a "container") is composed of other objects (call them the "elements"), then the elements will come into existence and also be destroyed as a side effect of creating or destroying the container. It would be rare for a element not to be declared as private. An example might be an Customer's name and address. A Customer without a name or address is a worthless thing. By the same token, when the Customer is destroyed, there's no point in keeping the name and address around. (Compare this situation with aggregation, where destroying the Committee should not cause the members to be destroyed---they may be members of other Committees).

In terms of implementation, the elements in a composition relationship are typically created by the constructor or an initializer in a field declaration, but Java doesn't have a destructor, so there's no way to guarantee that the elements are destroyed along with the container. In C++, the element would be an object (not a reference or pointer) that's declared as a field in another object, so creation and destruction of the element would be automatic. Java has no such mechanism. It's nonetheless important to specify a containment relationship in the UML, because this relationship tells the implementation/testing folks that your intent is for the element to become garbage collectible (i.e. there should be no references to it) when the container is destroyed).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment