Intent: Compose objects into tree structures that represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. A leaf has the same interface as a node.
Contrast this to the Restricted Composite Pattern discussed in CppUtxOverview that uses ExternalPolymorphism so that a leaf need not inherit the collection interface needed by a node.
See also: VisitorPattern, HierarchicalVisitorPattern, DesignPatterns
CommentsOnComposite, DarkSideOfCompositePattern, CompositePatternExample, CompositeConsideredHarmful, InterpreterVsComposite
A leaf does not have to have the same interface as the node base-class. It typically extends the node interface with methods that are not used polymorphically. Similarly, leaves do not usually implement collection interfaces. The composite node extends the basic node class with the collection behaviour and interface. -- AnonymousDonor
Hmmm.. Well I guess it depends on which description of the CompositePattern you follow. Are you saying that Leaf doesn't descend from Composite or that Composite doesn't define the collection interface? If we go back to the GangOfFour DesignPatternsBook, the Component class establishes an interface including Add( Component ), Remove( Component ), and GetChild( int ). The Leaf and Composite classes both descend from Component. In fact, if you go to the Participants section, the third bullet for Component states that a Component "declares an interface for accessing and managing its child components." What's optional is the fourth bullet, which are members for accessing a component's parent. What am I missing? While I prefer your comments and have always used Composite in this way, it seems to be a variation on the original CompositePattern. -- RobertDiFalco
The AnonymousDonor is wrong, and RobertDiFalco is right. In the DesignPatternsBook, we intended a Leaf to have the same interface as the base class, and for a Composite too, as well. The discussion on page 167-169 is based on that fact that it is usually impossible to make them all exactly the same, but it is worth trying. In practice, the interfaces are usually almost identical, but not quite. -- RalphJohnson
So what's the point of trying it?? Why is it worth trying? I cannot think of an example... Even in the Unix filesystem, where directories are files, the solution is to make Composite implement the interface of Leaf... -- Euyyn at Wikipedia
I sometime use (what I guess is) a degenerate CompositePattern in which the Leaf and Composite have the same interface as the base class, but only the Composite has the collection interface. In BNF:
<node> ::= <leafnode> | <compositenode> <compositenode> ::= <node>*Perhaps this would be better termed a CompoundPattern rather than CompositePattern (but this WikiWord is already taken). Comments? -- GeorgeDinwiddie
Right or wrong?
There are designs where the leaves should have dummy child management method, and designs where they shouldn't; structures which are not general trees or where the interface of Add( Component ), Remove( Component ), and GetChild( int ) is too free; algorithms which use parent links in the tree and algorithms which don't need them; and so on. There is a continuous space of possible solutions; the Composite as described in the DesignPatternsBook is a typical example, not the only right way to define aggregates. -- LorenzoGatti
This just in (June 2006): Rebecca Wirfs-Brock has written an article entitled "Refreshing Patterns" in the IEEE Software Magazine (Vol 23 No 3 May/June 2006)pages 45-47. She argues that patterns need to evolve and uses the CompositePattern as an example. Quotes one of the GoF authors... -- RichardBotting
By the way, why do we say that the CompositePattern makes a TreeStructure? Surely we can add components that are already part of the structure? Did the GoF discuss this? Doesn't the remove method need to be a little complicated to avoid collecting garbage twice? -- RichardBotting (I've been bitten by this bug in the past. It took months to diagnose.)
CompositePattern suggests NavigationalDatabase / ObjectOrientedDatabase and inherits many weaknesses thereof (especially in the face of concurrency). It is worth considering alternatives. If CompositePattern is being used to represent structured messages or values, consider use of immutable structures and functional construction (without SideEffects). If CompositePattern is being used to represent data - such as a world-model or SceneGraph or DocumentObjectModel - consider introducing a dedicated DataBase object, possibly one well proven to achieve both performance and flexibility, such as RelationalModel.
http://home.earthlink.net/~huston2/dp/composite.html
http://wiki.cs.uiuc.edu/patternStories/CompositePattern