We want to handle items that are hierarchically related (either through Classification or like a Bill of Material) as objects.
The most common example of a Composite is a hierarchical file system. Files are placed into folders, but folders can also contain other folders to any desired depth. The purpose of such a Composite is organizing (collecting files and folders that belong together), finding (the structure can be navigated in a search), and to eliminate name collision (many folders in a file system can contain a file named README.TXT, for example, with no naming collision).
Qualities and principles
Simple and complex structures can be modeled with no change to design. Clients couple to the interface but implementation can be hidden from them. The responsibilities of leaf (file) and node (folder) are singular and separate. Leaf and node objects can often be stored and retrieved interchangeably.
Leaf objects can be tested individually. Node objects can be tested using Mock leaf objects.
Questions and concerns
Composites come in two general forms: Classification (as in the example) and Bill of Material. The latter is used to model complex entities; for example, a budget has categories, the categories have line items, the line items have details, etc. Summing the categories may be the desired behavior.
One decision to make is whether to expose the difference between leaf and node objects. Leaf objects do not contain other elements while node objects do. If this difference is exposed to clients then this allows clients to traverse the structure but breaks the encapsulation of type. The correct balance of these factors is based on the problem context.
Varying node/leaf behavior can be accomplished with the Visitor without breaking type encapsulation.
This is Scott Bain. Visit us at www.netobjectives.com.