Composite pattern
From Wikipedia, the free encyclopedia
| This article or section is in need of attention from an expert on the subject. WikiProject Computer science or the Computer science Portal may be able to help recruit one. |
In computer science, the composite pattern is a partitioning 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]
Contents |
[edit] 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, if defining a system to portray grouped shapes on a screen, it would be useful to define resizing a group of shapes to have the same effect (in some sense) as resizing a single shape.
[edit] When to use
Composite can be used when clients should ignore the difference between compositions of objects and individual objects.[1] If programmers find that they 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 homogeneous.
Compose means a special thing: it refers to building objects using delegation. Delegation-composition hangs onto constituent parts-using references. By contrast, mixins inherit from each part. Mixins prevent returning a whole object 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]
[edit] Structure
[edit] 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 component's parent in the recursive structure, and implements it if that's appropriate
[edit] Leaf
- represents leaf objects in the composition
- implements all Component methods
[edit] Composite
- represents a composite Component (component having children)
- implements methods to manipulate children
- implements all Component methods, generally by delegating them to its children
[edit] 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. In algebraic form,
Graphic = ellipse | GraphicList
GraphicList = empty | ellipse GraphicList
It could be extended to implement several other shapes (rectangle, etc.) and methods (translate, etc.).
List = empty_list | atom List | List List
import java.util.List; import java.util.ArrayList; /** "Component" */ interface Graphic { //Prints the graphic. public void print(); } /** "Composite" */ class CompositeGraphic implements Graphic { //Collection of child graphics. private List<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); } } /** "Leaf" */ class Ellipse implements Graphic { //Prints the graphic. public void print() { System.out.println("Ellipse"); } } /** Client */ 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(); } }
C++ Example
#include <iostream> #include <vector> #include <string> using std::cout; using std::vector; using std::string; class Component { public: virtual void list() const = 0; virtual ~Component(){}; }; class Leaf : public Component { public: explicit Leaf(int val) : value_(val) { } void list() const { cout << " " << value_ << "\n"; } private: int value_; }; class Composite : public Component { public: explicit Composite(string id) : id_(id) { } void add(Component *obj) { table_.push_back(obj); } void list() const { cout << id_ << ":" << "\n"; for (vector<Component*>::const_iterator it = table_.begin(); it != table_.end(); ++it) { (*it)->list(); } } private: vector <Component*> table_; string id_; }; int main() { Leaf num0(0); Leaf num1(1); Leaf num2(2); Leaf num3(3); Leaf num4(4); Composite container1("Container 1"); Composite container2("Container 2"); container1.add(&num0); container1.add(&num1); container2.add(&num2); container2.add(&num3); container2.add(&num4); container1.add(&container2); container1.list(); return 0; }
[edit] 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
[edit] External links
- Composite pattern description from the Portland Pattern Repository
- Composite pattern in UML and in LePUS3, a formal modelling language
- Class::Delegation on CPAN
- Chinese Ring Puzzle Applet
- "The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects" by Paul Baranowski
[edit] References
- ^ a b Gamma, Erich; Richard Helm, Ralph Johnson, John M. Vlissides (1995). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 395. ISBN 0201633612.
| The references in this article would be clearer with a different or consistent style of citation, footnoting, or external linking. |
Parts of this article originated from the Perl Design Patterns Book
|
|||||||||||

