Composite pattern
![]() | This article needs attention from an expert in Computer science. Please add a reason or a talk parameter to this template to explain the issue with the article. |
In computer science, the composite pattern is a structural design pattern. Composite allows a group of objects to be treated in the same way as a single instance of an object. The intent of Composite is to "compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions uniformly."[1]
Motivation
When dealing with tree-structured data, programmers often have to discriminate between a leaf-node and a branch. This makes code more complex, and therefore, error prone. The solution is an interface that allows treating complex and primitive objects uniformly. In object-oriented programming, a Composite is an object (e.g. a shape) designed as a composition of one-or-more similar objects (other kinds of shapes/geometries), all exhibiting similar functionality. This is known as a "has-a" relationship between objects. The key concept is that you can manipulate a single instance of the object just as you would a group of them. The operations you can perform on all the composite objects often have a least common denominator relationship. For example, when resizing a single shape to fill the screen, surely you would expect/desire that resizing a group of shapes would have the same effect.
When to use
Composite can be used when clients should ignore the difference between compositions of objects and individual objects.[1]. If you find that you are using multiple objects in the same way, and often have nearly identical code to handle each of them, then Composite is a good choice; it is less complex in this situation to treat primitives and composites as homogenous.
Compose means a special thing: it refers to building objects using DelegationConcept. Delegation-composition hangs onto constituent parts-using references. By contrast, mixins inherit from each part. MixIns prevent returning a WholeObject in response to requests for information, and they prevent having more than one of any given part.
The composite pattern is an object oriented pendant to algebraic data types.[citation needed]
Structure
![The class "Component" derives "Composite" and "Leaf". A composite has 0 components or more.](http://upload.wikimedia.org/wikipedia/commons/thumb/6/68/Composite_UML_class_diagram.svg/480px-Composite_UML_class_diagram.svg.png)
Component
- is the abstraction for all components, including composite ones
- declares the interface for objects in the composition
- implements default behavior for the interface common to all classes, as appropriate
- declares an interface for accessing and managing its child components
- (optional) defines an interface for accessing a components's parent in the recursive structure, and implements it if that's appropriate
Leaf
- represents leaf objects in the composition
- implements all Component methods
Composite
- represents a composite Component (component having children)
- implements methods to manipulate children
- implements all Component methods, generally by delegating them to its children
Example
The following example, written in Java, implements a graphic class, which can be either an ellipse or a composition of several graphics. Every graphic can be printed.
It could be extended to implement several other shapes (rectangle etc.) and methods (translate etc.).
import java.util.ArrayList;
interface Graphic {
//Prints the graphic.
public void print();
}
class CompositeGraphic implements Graphic {
//Collection of child graphics.
private ArrayList<Graphic> mChildGraphics = new ArrayList<Graphic>();
//Prints the graphic.
public void print() {
for (Graphic graphic : mChildGraphics) {
graphic.print();
}
}
//Adds the graphic to the composition.
public void add(Graphic graphic) {
mChildGraphics.add(graphic);
}
//Removes the graphic from the composition.
public void remove(Graphic graphic) {
mChildGraphics.remove(graphic);
}
}
class Ellipse implements Graphic {
//Prints the graphic.
public void print() {
System.out.println("Ellipse");
}
}
public class Program {
public static void main(String[] args) {
//Initialize four ellipses
Ellipse ellipse1 = new Ellipse();
Ellipse ellipse2 = new Ellipse();
Ellipse ellipse3 = new Ellipse();
Ellipse ellipse4 = new Ellipse();
//Initialize three composite graphics
CompositeGraphic graphic = new CompositeGraphic();
CompositeGraphic graphic1 = new CompositeGraphic();
CompositeGraphic graphic2 = new CompositeGraphic();
//Composes the graphics
graphic1.add(ellipse1);
graphic1.add(ellipse2);
graphic1.add(ellipse3);
graphic2.add(ellipse4);
graphic.add(graphic1);
graphic.add(graphic2);
//Prints the complete graphic (four times the string "Ellipse").
graphic.print();
}
}
See also
- Design Patterns: The book that started it all.
- Mixin
- Facade pattern
- Decorator pattern
- Law of Demeter
- Delegation pattern
- Builder pattern
- Abstract factory pattern
External links
- Description from the Portland Pattern Repository
- Class::Delegation on CPAN
- Chinese Ring Puzzle Applet
- "The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects" by Paul Baranowski
- Composite pattern discussion with 1-page examples by Vince Huston
- A persistent implementation of the Composite Pattern using Hibernate
- Note the above isn't a representation of the Composite Pattern
- University of Sydney COMP5028 Object Oriented Analysis and Design
References
![]() | This article has an unclear citation style. |
Parts of this article originated from the Perl Design Patterns Book