locked
Composite Pattern RRS feed

  • Question

  • I have being going thought the book "Design Patterns - Elements of Reusable Object Oriented Software", and have begun working with the composite pattern.

    I am trying to set-up the pattern so that a child can have multiple parents.  According to the Gang of Four, the way to do this is to define the parent reference in the component class so that the leaf and the composite classes can inherit the reference and the operations that manage it.

     

    To that effect, here is the code that I am using:

    The Component

    [code]

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace CompositePattern

    {

    abstract class AbstractEmployee : CompositePattern.IAbstractEmployee

    {

    public string name;

    public string title;

    public decimal salary;

    //This is a list of references for all my parents. See GoF pg166(Implementation pt1.) for reasoning.

    public List<AbstractEmployee> myParents = new List<AbstractEmployee>();

    public AbstractEmployee(string name, string title, decimal salary)

    {

    this.name = name;

    this.title = title;

    this.salary = salary;

    }

    //Add a leaf to a parent, or add a parent to another parent.

    public abstract void Add(AbstractEmployee employee);

    //Remove a leaf from a parent.

    public abstract void Remove(AbstractEmployee employee);

    //Display all the leaves for a particular parent.

    public abstract void Display(int indent);

    //Get the name of the parent/leaf.

    public abstract string GetName();

    //Get the salary of the parent/leaf.

    public abstract string GetTitle();

    //Get the salary of the parent/leaf.

    public abstract decimal GetSalary();

    //Add a new reference to the object for a new parent.

    public abstract void AddParentReference(AbstractEmployee myParentRef);

    //List all the references to parents that an object has.

    public abstract void ListParentReference();

    public abstract void RemoveReferences(CompositeElement myParentRef);

    }

    }

    [/code]

     

    The Composite

    [code]

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace CompositePattern

    {

    class CompositeElement: AbstractEmployee

    {

    List<AbstractEmployee> myElements = new List<AbstractEmployee>();

    public CompositeElement(string name, string title, decimal salary): base(name, title, salary)

    {

    }

    //Add an employee to the manger.

    public override void Add(AbstractEmployee myEmployee)

    {

    myElements.Add(myEmployee);

    }

    //Remove an employee from the manger.

    public override void Remove(AbstractEmployee myEmployee)

    {

    myElements.Remove(myEmployee);

    }

    //1. Begin by printing the name of the parent, 2. followed by its children.

    public override void Display(int indent)

    {

    //1. Print the name of the parnet.

    Console.WriteLine(new string('-', indent) + "+ " + name);

    //2. Print all the children of the parent.

    foreach (AbstractEmployee myEmployee in myElements)

    {

    myEmployee.Display(indent + 1);

    }

    }

    //Return the name of a parent.

    public override string GetName()

    {

    return name;

    }

    //Return the title of the parent.

    public override string GetTitle()

    {

    return title;

    }

    //Return the salary of the parent.

    public override decimal GetSalary()

    {

    return salary;

    }

    //Add a reference to the parent.

    public override void AddParentReference(AbstractEmployee myParentRef)

    {

    myParents.Add(myParentRef);

    }

    //List all the references that the parent has to other parents.

    public override void ListParentReference()

    {

    if (myParents.Count == 0)

    {

    Console.WriteLine("No references exist.");

    }

    else

    {

    //1. Print the name of the parnet.

    Console.WriteLine(new string('-', 1) + "+ " + name);

    int counter = 0;

    //Print all the references that the object has to parents.

    foreach (AbstractEmployee myRef in myParents)

    {

    counter += 1;

    Console.WriteLine("Reference " + counter + ": " + myRef.GetName());

    }

    }

    }

    //Remove a reference to a parent.

    public override void RemoveReferences(CompositeElement myParentRef)

    {

    myParents.Remove(myParentRef);

    }

    }

    }

    [/code]

     

    The Leaf

    [code]

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace CompositePattern

    {

    class Employee: AbstractEmployee

    {

    public Employee(string name, string title, decimal salary):base(name, title, salary)

    {

    }

    public override void Add(AbstractEmployee myEmployee)

    {

    Console.WriteLine("Cannot ADD to an employee, operation can only be performed on an manager.");

    }

    public override void Remove(AbstractEmployee myEmployee)

    {

    Console.WriteLine("Cannot REMOVE from an employee, operation can only be performed on an manager.");

    }

    //Display the employee.

    public override void Display(int indent)

    {

    Console.WriteLine(new string('-', indent) + " " + name);

    }

    //Get the name of the employee.

    public override string GetName()

    {

    return name;

    }

    //Get the title of the employee.

    public override string GetTitle()

    {

    return title;

    }

    //Get the salary of the employee.

    public override decimal GetSalary()

    {

    return salary;

    }

    //Add a reference to the child.

    public override void AddParentReference(AbstractEmployee myParentRef)

    {

    //Console.WriteLine("Cannot ADD_PARENT_REFERENCE from an employee, operation can only be performed on an manager.");

    myParents.Add(myParentRef);

    }

    //List all the references that the child has to other parents.

    public override void ListParentReference()

    {

    if (myParents.Count == 0)

    {

    Console.WriteLine("No references exist.");

    }

    else

    {

    //1. Print the name of the parnet.

    Console.WriteLine(new string('-', 1) + "+ " + name);

    int counter = 0;

    //Print all the references that the object has to parents.

    foreach (AbstractEmployee myRef in myParents)

    {

    counter += 1;

    Console.WriteLine("Reference " + counter + ": " + myRef.GetName());

    }

    }

    }

    //Remove a reference to a parent.

    public override void RemoveReferences(CompositeElement myParentRef)

    {

    myParents.Remove(myParentRef);

    }

    }

    }

    [/code]

     

    And finally, the code in the main class

    [code]

    //1. Create the primary parent.

    CompositeElement root = new CompositeElement("PJimmy", "Managing Director", 100000);

    CompositeElement comp = new CompositeElement("PMichael", "Developer", 17000);

    //2. Create an employee and add a reference.

    Employee emp = new Employee("Tom", "Quality Manager", 50000);

    emp.AddParentReference(root);

    emp.AddParentReference(comp);

    comp.AddParentReference(root);

    //Display the references.

    emp.ListParentReference();

    [/code]

     

    Can anyone tell me if I am going about it the correct way, or am I doing it completely wrong.

     

    Michael.

    Saturday, March 10, 2007 4:22 PM