class Composition
• Thorsten Reitz
Intent
Composition is a strong form of object combination, where a whole data structure is made of parts belonging to one or more classes, such as a car also having an engine and four wheels. In software engineering, we often make a distinction between composition and aggregation:
- In composition, the lifecycle of the contained object is bound to the lifecycle of the containing object. There is exactly one object that owns the contained objects.
- In aggregation, the lifecycle of the contained object is independent of the lifecycle of the containing object. The contained object (“containee”) can thus exist independently and be shared by more than one containing object.
In composition, your extension object always contains an INSPIRE object. If the lifecycle of your extension object ends, the INSPIRE object would have to be removed as well. The other way around is not possible since you can’t modify the INSPIRE class to add the new relation.
If you discover need for a composition, make sure you resolve the associated organisational issues that come from ownership of the composed class. You should only use composition between data sets maintained by different organisations if you also have a trusted working relationship with these organisations.
Structure
In composition, there is a containing class and a contained class. They are connected through an Composition association which points from the containing class to the contained class:
When to use
Composition is a very versatile, well-supported pattern, and has several applicable uses:
- When there is a clear whole-part relationship between the objects
- When the lifecycle of the composed objects is linked
- When inheritance is not applicable because the
is-a
statement is not true and would break proper encapsulation.
When not to use
Composition implies a contains/contained relationship, and often also mandates linked lifespans. It is thus not suitable for coupling of loosely related objects:
- You want to point at a related object where there is no composition (e.g. neighboringHouse)
- You want to link objects that have a different lifecycle
- You need a many-to-many relationship between containers and containees
- You need shared ownership, where a containee can be part of multiple containers (e.g. a
Student
is in multipleCourse
s)
XML Schema Example
A potential schema structure for the composition pattern is as follows:
In line 23, we define the contained property like any other property in the sequence. We declare it to be of type ex:OwnerType
. This schema allows us to do different types of encodings for the instance, as described below.
XML Instance Example
Composition is highly similar to adding a property to your class, to a degree that it’s indistinguishable on the encoding level. Instances using this pattern are usually encoded using an in-place encoding:
This encoding strategy means we can’t re-use contained objects. Please refer to the association or aggregation patterns to learn how an object can be shared by many ex:JoinedParcel
containers.
Implementation Considerations
This section provides information when and how this pattern can be implemented on different types of platforms.
Storage Backend
Composition is well-supported by all types of storage backends. In-line encoding in document-oriented backends has the advantage of not requiring joins.
Download Services
This pattern can be implemented on XML-based platforms without special considerations.
Business Logic
This pattern can be implemented on object-oriented platforms without special considerations.
Consumer Side
Many GIS applications support nested composition structures to some degree. As an example, ArcGIS geodatabases support Relationship classes and client-sied Relates, which you can use to define both aggregation and composition associations between different classes. However, it’s not possible to use nested properties for styling or in many analytic tools. For this purpose, you have to use client-side Joins.