Composite pattern

Composite is a structural design patterns.

Via wikipedia:

The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to “compose” objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.

 In short, we combine multiple objects into one, without losing access to a specific object
composite pattern

Component – An interface that defines the behavior for a particular object or group of objects

Leaf – Single object that has no descendants, implements the interface Component

Composite -Group of objects, consiting of leaves, implements the interface Component

Example

Let’s see how it works on a simple example of how to solve the equation ((((2+5)-1)*4)/3).

 In a first step, we write interface.
// Component - Common interface for nodes and leafs
public interface IOperation
{
    // Calculate the value of expresseion
    double Calculate();

    // display expression
    string Show();
}
 Now we implement leaf class that represents a single number / result.
//leaf
public class Number : IOperation
{
    public double a { get; set; }
    public Number(double _a)
    {
        a = _a;
    }
    public double Calculate()
    {
        return a;
    }

    public string Show()
    {
        return a.ToString();
    }
}

Now we implement classes(composite) that represent arithmetic operations like addition, multiplication, divide and subtraction.

//composite
public class Add : IOperation
{
    public IOperation b1 { get; set; }
    public IOperation b2 { get; set; }

    public Add(IOperation a1, IOperation a2)
    {
        b1 = a1;
        b2 = a2;
    }
    public double Calculate()
    {
        return b1.Calculate() + b2.Calculate();
    }

    public string Show()
    {
        return "(" + b1.Show() + "+" + b2.Show() + ")";
    }
}

And the same will be in other classes with arithmetic operations only difference is a method of Calculate and Show

Divide:

public double Calculate()
{
    return b1.Calculate() / b2.Calculate();
}

public string Show()
{
    return "(" + b1.Show() + "/" + b2.Show() + ")";
}

Multiplication:

public double Calculate()
{
    return b1.Calculate() * b2.Calculate();
}

public string Show()
{
    return "(" + b1.Show() + "*" + b2.Show() + ")";
}

Subtraction:

public double Calculate()
{
    return b1.Calculate() - b2.Calculate();
}

public string Show()
{
    return "(" + b1.Show() + "-" + b2.Show() + ")";
}

Now let’s apply our pattern for the calculation of expression ((((2 + 5) -1) * 4) / 3)

static void Main(string[] args)
{
    // build the following expression ((((2+5)-1)*4)/3)
    Number a = new Number(2);
    Number b = new Number(5);
    Add addition = new Add(a, b);

    Number c = new Number(1);
    Sub subtraction = new Sub(addition, c);

    Number d = new Number(4);
    Multi multiplication = new Multi(subtraction, d);

    Number e = new Number(3);
    Div divide = new Div(multiplication, e);

    Console.WriteLine("Result of: {0} is: {1}", divide.Show(), divide.Calculate());
    Console.WriteLine("Result of: {0} is: {1}", multiplication.Show(), multiplication.Calculate());

    Console.ReadKey();
}

As u see in this approach we combine multiple objects into a single object and we perform methods on it. We can also refer to any of these objects.

 Composite patter

Summary

Compsite patter we can apply where we got a simillar objects and we can merge them into one, without losing access to a specific object eg. take total cost from one objects which is the sum of all objects(these objects can have different methods to count their own costs) but we still have access to the cost of each object.
In this way we can manipulate large amounts of objects instead refer to them individually, we can call a method on the entire group.

Link to the project : here

 

2 Comments on “Composite pattern”

Leave a Reply

Your email address will not be published. Required fields are marked *