 .NET 1.1+Composite Design PatternThe composite pattern is a design pattern that is used when creating hierarchical object models. The pattern defines a manner in which to design recursive tree structures of objects, where individual objects and groups can be accessed in the same manner.
What is the Composite Pattern?
The composite pattern is a Gang of Four design pattern. This is a structural pattern as it defines a manner for creating relationships between classes or entities. The composite design pattern is used to create hierarchical, recursive tree structures of related objects where any element of the structure may be accessed and utilised in a standard manner. This includes individual leaf objects and those at any branch of the tree.
An example use of the composite pattern is for representing management structures in an organisation. In such a structure, each employee object can be the manager or zero or more subordinates.
Implementing the Composite Pattern

The UML class diagram above describes an implementation of the composite design pattern. The items in the diagram are described below:
- Component. This abstract class is the base class for all objects that can appear within the hierarchical tree structure. The base class defines any standard members that will be implemented by all objects in the hierarchy. If you do not wish to create any actual functionality in this class you may decide to use an interface instead.
- Composite. The Composite class is the key element of the design pattern. This class includes methods to add and remove child components and to retrieve those children from a private array or collection. Each of those components could also be a composite containing its own children. In the diagram the Composite class implements the generic IEnumerable interface. This interface is not actually a part of the basic composite design pattern. It is included here as often you will want to allow the use of a foreach loop to iterate through an object's children.
- Leaf. This class is used to define components within the tree that cannot have children.
The following shows the basic code of the component design pattern implemented using C#. An iterator has been included to allow the use of the foreach command to traverse the children of any composite node in the tree. This uses the C# iterator syntax provided in C# 2.0. If you wish to use an earlier version of the language you must replace this with full implementations of the IEnumerable interfaces.
NB: The sample code uses the System.Collections namespace so ensure that you have included the using System.Collections; directive in the code.
public abstract class Component
{
public abstract void Operation();
}
public class Composite : Component, IEnumerable<Component>
{
private List<Component> _children = new List<Component>();
public void AddChild(Component child)
{
_children.Add(child);
}
public void RemoveChild(Component child)
{
_children.Remove(child);
}
public Component GetChild(int index)
{
return _children[index];
}
public override void Operation()
{
string message = string.Format("Composite with {0} child(ren)."
, _children.Count);
Console.WriteLine(message);
}
public IEnumerator<Component> GetEnumerator()
{
foreach (Component child in _children)
yield return child;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Leaf : Component
{
public override void Operation()
{
Console.WriteLine("Leaf.");
}
}
Example Composite
Earlier in this article I mentioned that the composite design pattern could be used to create an object model that represents a company's management structure. In this section, we will create this example and demonstrate its use. In this case, the base class will be replaced with the IEmployed interface. We will also define an Employee class, which is the composite, and a Contractor class. Contractors will be leaf nodes in the hierarchical tree as they are managed but are unable to have subordinates.
The following code shows the elements that are required to obtain the required information:
public interface IEmployed
{
string Name { get; set; }
}
public class Employee : IEmployed, IEnumerable<IEmployed>
{
private List<IEmployed> _subordinates = new List<IEmployed>();
private string _name;
public void AddSubordinate(IEmployed subordinate)
{
_subordinates.Add(subordinate);
}
public void RemoveSubordinate(IEmployed subordinate)
{
_subordinates.Remove(subordinate);
}
public IEmployed GetSubordinate(int index)
{
return _subordinates[index];
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public IEnumerator<IEmployed> GetEnumerator()
{
foreach (IEmployed subordinate in _subordinates)
{
yield return subordinate;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public class Contractor : IEmployed
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
Testing the Composite
To test the composite, we need a sample hierarchy to create. In our example, we will create objects to represent nine employees in a management structure. Three of the employees (Bob, Sue and John) will have subordinates. Of the subordinates, Sam and Tim will be contractors with no ability to have subordinates. Rita, Jim, Lou, Phil and Sam will be normal employees that could have subordinates but do not.

The code to create these nine employees and build the management structure is as follows:
Employee bob = new Employee();
bob.Name = "Bob";
Employee sue = new Employee();
sue.Name = "Sue";
bob.AddSubordinate(sue);
Employee john = new Employee();
john.Name = "John";
bob.AddSubordinate(john);
Employee rita = new Employee();
rita.Name = "Rita";
sue.AddSubordinate(rita);
Employee jim = new Employee();
jim.Name = "Jim";
sue.AddSubordinate(jim);
Employee lou = new Employee();
lou.Name = "Lou";
john.AddSubordinate(lou);
Employee phil = new Employee();
phil.Name = "Phil";
john.AddSubordinate(phil);
Contractor sam = new Contractor();
sam.Name = "Sam";
john.AddSubordinate(sam);
Contractor tim = new Contractor();
tim.Name = "Tim";
john.AddSubordinate(tim);
To test the hierarchical nature of the structure, we can output the names of the first employee, his managers and the managers' subordinates using two foreach loops:
Console.WriteLine(bob.Name);
foreach (Employee manager in bob)
{
Console.WriteLine(" {0}", manager.Name);
foreach (IEmployed employee in manager)
{
Console.WriteLine(" {0}", employee.Name);
}
}
/* Output
Bob
Sue
Rita
Jim
John
Lou
Phil
Sam
Tim
*/
|