BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 1.1+

Composite Design Pattern

The 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.

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.

Management Structure

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

*/
21 December 2008