Jump to content

Composite pattern: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
m Remove "Article with example XXX code" since the examples has been removed
Line 121: Line 121:
*[http://www.cs.oberlin.edu/~jwalker/puzzle/ Chinese Ring Puzzle Applet]
*[http://www.cs.oberlin.edu/~jwalker/puzzle/ Chinese Ring Puzzle Applet]
*[http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/149878 "The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects"] by [[Paul Baranowski]]
*[http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/149878 "The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects"] by [[Paul Baranowski]]
*[http://home.earthlink.net/~huston2/dp/composite.html Composite Pattern] by Vince Huston
*[http://www.vincehuston.org/dp/composite.html Composite pattern discussion] with 1-page examples by [[Vince Huston]]
*[http://www.researchkitchen.co.uk/blog/archives/57 A persistent implementation of the Composite Pattern using Hibernate]
*[http://www.researchkitchen.co.uk/blog/archives/57 A persistent implementation of the Composite Pattern using Hibernate]
*Note the above isn't a representation of the Composite Pattern
*Note the above isn't a representation of the Composite Pattern

Revision as of 03:22, 6 October 2007

In computer science, the composite pattern is a design pattern: "A general solution to a common problem in software design." Composite allows a group of objects to be treated in the same way as a single instance of an object.

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: You find that you are using multiple objects in the same way, and often have nearly identical code to handle each of them -- the only differences being that you are manipulating an instance of a 'circle' versus a 'square', for instance. Useful if differentiation doesn't need to exist, and it would be easier to think of them as homogeneous. (Of course, you could still provide functionality to manipulate only a single instance -- like selecting an item from a list instead of operating on the whole list.)

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.

Structure

The class "Component" derives "Composite" and "Leaf". A composite has 0 components or more.
The class "Component" derives "Composite" and "Leaf". A composite has 0 components or more.
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

References

Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. 1995. p. 395. ISBN 0201633612. {{cite book}}: Unknown parameter |coauthors= ignored (|author= suggested) (help)


Parts of this article originated from the Perl Design Patterns Book