Tree - Composite (Design Pattern)

1 - Preconditions

A composite object is an object with many components; a folder consists of a set of documents, a book consists of a set of chapters, a company consists of a set of departments.

The intent of a composite is to “compose” objects into tree structures to represent part-whole hierarchies.

A composite is an object designed as a composition of one-or-more similar objects, all exhibiting similar functionality. This is known as a “has-a” relationship between objects. The operations you can perform on all the composite objects often have a least common denominator relationship.

3 - Problem

A naive modeling of composite objects leads to many similar classes specialized primarily by the types of their components.

4 - Constraints

Consider a text editing system with “chapter”, “section”, “subsection”, “paragraph”, “word”, “item” etc. We could have a large number of classes, each of which was really just a collection of its components. Some have titles, some always start a new page, but in general they are quite similar. On the one hand, the composite object is “obviously” different from its components. On the other hand, it is easier to reuse and understand a design that minimizes the number of classes by making its classes be polymorphic and composable in any combination. We don't want to make every “text-element” have a list of components; some will be atomic. But we would like a scheme that lets us avoid having to duplicate code and to design a lot of classes.

5 - Model

where:

  • Component is an interface defining the common objects methods
  • Leaf represents leaf objects in the composition (hierarchy) and implements all Component methods
  • Composite represents a composite Component (a parent component having children) implements methods to manipulate children implements all Component methods, generally by delegating them to its children

6 - Example

  • Component
interface Graphic {
 
    //Prints the graphic.
    public void print();
}
  • Leaf
class Ellipse implements Graphic {
 
    //Prints the graphic.
    public void print() {
        System.out.println("Ellipse");
    }
}
  • Composite
import java.util.List;
import java.util.ArrayList;
class CompositeGraphic implements Graphic {
 
    //Collection of child graphics.
    private List<Graphic> childGraphics = new ArrayList<Graphic>();
 
    //Prints the graphic.
    public void print() {
        for (Graphic graphic : childGraphics) {
            graphic.print();
        }
    }
 
    //Adds the graphic to the composition.
    public void add(Graphic graphic) {
        childGraphics.add(graphic);
    }
 
    //Removes the graphic from the composition.
    public void remove(Graphic graphic) {
        childGraphics.remove(graphic);
    }
}
  • 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();
    }
}

7 - Documentation / Refrerence

data/type/tree/composite.txt · Last modified: 2017/09/13 16:14 by gerardnico