Instantiation creates an object instance (many languages are using the new
keyword for this) while aggregation describes the relationship between objects (that are already created or instantiated).
To prevent confusion I have to point out that all terms used in this example like aggregation are used in the context of Martin Fowler, who has introduced a different definition or phrasing in contrast to the UML standard definition.
From your diagram:
Aggregation
given are the two class definitions Drawing
and Shape
that have, according to your provided diagram, a relationship which is called aggregation, which by definition describes a shared lifetime of those two objects. This means a Drawing
'consists' of an arbitrary number of Shapes
or to be more precise a Shape
is part of a Drawing
. When the lifetime of the owner (Drawing
) ends, then also the lifetime of Shape
will end:
// The `Shape` class
class Shape
{
...
}
// The `Drawing`class that aggregates a single `Shape`
class Drawing
{
// The reference to the instance of `Shape`
private Shape shape;
// The constructor
public Drawing()
{
// Create an instance of `Shape`.
// Because the relationship between `Drawing`and `Shape`is an aggregation the instantiation occurs inside the owners constructor (opposed to outside the owner object).
this.shape = new Shape();
}
}
Because the relationship between Drawing
and Shape
is an aggregation the instantiation of the type Shape
occurs inside the owners constructor (opposed to outside the owner object in case of acquaintance).
Acquaintance
The other relationship that is pictured by the diagram is the acquaintance. Acquaintance exist between the object of type LineShape
and Color
. This means a LineShape
uses a Color
. Color
will live independent from its owning LineShape
object. The dashed line between the objects CreationTool
and LineShape
describes an instantiation (create). This means that CreationTool
creates the instance of LineShape
. This is required since opposed to aggregation acquaintance describes an independent lifetime of both objects. Color
could be shared between other Shape
objects. This requires the related objects of LineShape
, the Color
object, to be instantiated outside the owner (and not inside the owner's constructor like in an aggregation scenario):
// The `LineShape` class
class Color
{
...
}
// The `LineShape`class that acquaints or associates with a single `Color`
class LineShape
{
// The reference to the instance of `Shape`
private Color color;
// The constructor
public LineShape(Color sharedColorInstance)
{
// Request an instance of `Shape` as constuctor parameter.
// Because the relationship between `LineShape`and `Color`is an acquaintance the instantiation occurs outside the owners constructor (opposed to inside the owner object).
this.color = sharedColorInstance;
}
}
// The `CreationTool` class that creates an instance of `LineShape
// and passes a shared instance of `Color`into the constructor.
class CreationTool
{
Color color = new Color();
// Create the instance of `LineShape`
// to satisfy the dashed line (relationship) in the diagramm
LineShape firstLine = new LineShape(color);
// To show the benefit of acquaintance a second instance of `LineShape` is created
// using the same `Color` instance
LineShape secondLine = new LineShape(color);
// When firstLine's lifetime ends,
// secondLine still has a valid instance of `Color`
}
Because the relationship between LineShape
and Color
is an acquaintance the instantiation occurs outside the owners constructor (opposed to inside the owner object like in an aggregation scenario). This way a single instance of Color
could be shared among multiple owners.
As you can see in the code examples both relations (or relations in general) require the reference, pointing to the related object(s), to be stored inside the owning object. The only difference is when looking at where the owned object was created. This circumstance will describe the special form of the relationship: was the related object instantiated outside the owner (acquaintance) or was it instantiated inside the owner (aggregation)?
This means you can distinguish this two types of relationship by looking at the constructor (or instantiation): is the related object instance passed to the constructor or a setter method of the owner (acquaintance) or is the owner's constructor parameter-less or setter-less (aggregation)?
For instantiation the requirement of a field is a different story. We can say that when CreationTool
instantiates LineShape
it does not need a field to store a reference to this object. But in case of the Color
the CreationToolobject
can store the reference to the Color
instance in a field in order to reuse it (share it) when creating new LineShape
instances, since an instance of Color
is needed to satisfy the constructor of LineShape
. So if a field to store the reference to the created instance inside the creator is required is totally optional in first place and depends on the context.
It should be mentioned at this point, that in case of acquaintance, another way to 'inject' the owned object instance is to use a setter method:
Color color = new Color();
LineShape shape = new LineShape();
shape.SetColor(color);
Using the constructor should be the prefered way whenever possible.
Another note, just to make it more complete: when the language used to implement such relationships has automatic memory management (garbage collection), then the aspect of lifetime controlling is no more relevant. Everything becomes acquaintance in M. Fowlers world (or aggregation in the UML world), since as long as there is any references stored to the owned object instance (e.g. when exposing the instance via a getter method), the garbage collector won't destruct this instance and it will continue to live - independent from the owner.