Structural Patterns
Composite Pattern
A Composite is a tree structure consisting of individual objects mixed with compositions of objects, that is, objects that have other objects as their children. The goal of the Composite pattern is to be able to treat individual objects and compositions of objects the same way. All objects in the Composite are derived from Composite itself.
The Gang Of Four (GoF) defined the Composite pattern as follows in their most famous book "Design Patterns" Gamma et al., Addison-Wesley, ISBN:0-201-63361-2" - "Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly."
The key to a composite pattern is an abstract class that represents both primitives (individual objects) and their containers (compositions of objects). Define an abstract base class (Component) that specifies the behavior that needs to be exercised uniformly across all primitive and composite objects. Subclass the Primitive and Composite classes off of the Component class. Each Composite object "couples" itself only to the abstract type Component as it manages its "children".
Non-software Example
Although the example is abstract, arithmetic expressions are Composites. An arithmetic expression consists of an operand, an operator (+ - * /), and another operand. The operand can be a number, or another arithmetic expression. Thus, 2 + 3 and (2 + 3) + (4 * 6) are both valid expressions. [Michael Duell, "Non-software examples of software design patterns", Object Magazine, Jul 97, p54]
The UML representation of a Composite pattern is shown below.
In the above diagram Leaf and Composite are type of component. The difference is that the Composite can contain other components either other Composites or Leafs as child components. But the Client treats both Leaf and Composite as just a Component.
C# Implementation
// Structural Pattern:COMPOSITE
using System;
using System.Collections;
//the single interface for primitives & composite types.|
abstract class Component
{
abstract public void AddChild(Component c);
abstract public void Traverse();
}
//A primitive type.
class Leaf : Component
{
private int value = 0;
public Leaf(int val)
{
value = val;
}
public override void AddChild(Component c)
{
//no action; This method is not necessary for Leaf
}
public override void Traverse()
{
Console.WriteLine("Leaf:"+value);
}
}
//A composite type.
class Composite : Component
{
private int value = 0;
private ArrayList ComponentList = new ArrayList();
public Composite(int val)
{
value = val;
}
public override void AddChild(Component c)
{
ComponentList.Add(c);
}
public override void Traverse()
{
Console.WriteLine("Composite:"+value);
foreach (Component c in ComponentList)
{
c.Traverse();
}
}
}
class MyMain
{
public static void Main()
{
//creating a TREE structure.
Composite root = new Composite(100);// Root
Composite com1 = new Composite(200); //Composite 1
Leaf l1 = new Leaf(10);//Leaf1
Leaf l2 = new Leaf(20);//Leaf2
//Add two leafs to composite1
com1.AddChild(l1);
com1.AddChild(l2);
Leaf l3 = new Leaf(30);//Leaf3
root.AddChild(com1);//Add composite1 to root
root.AddChild(l3);//Add Leaf3 directlt to root
root.Traverse();//Single method for both types.
}
}