Composite Design Pattern

What is Composite Design Pattern?

  • The Composite Design Pattern falls under Structural Design Pattern.
  • The primary motive of the Composite Design Pattern is to represent an object through a structure.
  • It is used where we need to treat a group of objects similarly as a single object.
  • The objects would be represented in a tree structure.
  • It contains two categories of objects which are Leaf and Composite.
  • Composite: It can have other leaf objects.
  • Leaf: It mustn’t have any children objects.
  • GOF definition “Compose objects into a tree structure to represent part-whole hierarchies. Composite lets the client treat individual objects and compositions of objects uniformly“.

Table of Contents

Real Life Examples of Composite Design Pattern

Example 1:

car photoLet’s consider a car. Car has an engine and a tire. The engine is made up of some electrical components and valves. The electrical components would further consist of some chips and transistors. These components make a complex object called a car.First, we will classify Leaf and Composite in our complex object (car). Here car engine’s electrical components are composite objects. Here car has child objects, engine and tires and engine has child objects, components, and valves. While tires, valves, and electrical components do not consist of any child objects. So these considered as Leaf objects. Let’s suppose if you apply some operation on these child objects. For example “getPrice()” is a method which can be applied on transistor object, chips object, valves, and tires. Here the pricing is being applied on these leaf objects. Then that operation should also be applied on the composite objects which are car and engine components. So with the leaf objects, you can also get the price of the car and engine components. As all the rules are applied, this would be considered as Composite Design Pattern. There are various criteria and use cases in real life examples where you would use Composite Design Pattern to solve real-time problems.

When to use the Composite Design Pattern?

  • When you want to represent the objects in a tree-like hierarchy. 
  • When the operations that are performed on leaf objects should also be performed on the composite objects.
  • Example: getPrice() can be performed on “Personal computer” which is a composite object, and it can also be performed on Keyboard which is a leaf object.

Composite Design Pattern Implementation Use Case

  • If we are working for a software company, there would be n number of hierarchies. Example: Developer, Manager, etc.
  • Here, Developer and Manager are the leaf nodes according to our use case.
    • There would be some admin person who holds all the employee details that would be treated as a composite class.

UML Class Diagram of Composite Design Pattern

Composite Design Pattern Java Implementation

Step 1: Create an abstract class "Employee"

public abstract class Employee
{    
    public abstract void printEmployeeDetails();
}

Step 2: Create a class "Manager" which extends "Employee"

public class Manager extends Employee
{

    protected String name;
    protected long empID;
    protected String designation;

    public Manager(String name, long empID)
    {
        this.name = name;
        this.empID = empID;
    }
    @Override
    public void printEmployeeDetails()
    {
        System.out.println("Name:" + name + " empID:" + empID + " Designation:Manager");
    }
    
}

Step 3: Create a class "Developer" which extends "Employee"

public class Developer extends Employee
{

    protected String name;
    protected long empID;
    protected String designation;

    public Developer(String name, long empID)
    {
        this.name = name;
        this.empID = empID;
    }

    @Override
    public void printEmployeeDetails()
    {
        System.out.println("Name:" + name + " empID:" + empID + " Designation:Developer");
    }

}

Step 4: Create a class "CompanyDirectory" which extends "Employee" class

public class CompanyDirectory extends Employee
{

    private List employeeList;

    public CompanyDirectory()
    {
        employeeList = new ArrayList<>();
    }

    @Override
    public void printEmployeeDetails()
    {
        for (Employee employee : employeeList)
        {
            employee.printEmployeeDetails();
        }
    }
    
    public void addEmployee(Employee employee)
    {
        employeeList.add(employee);
    }

}

Step 5: Create a class "CompanyDetails" which extends "CompanyDirectory" class

public class CompanyDetails extends CompanyDirectory
{
    private String companyName;
    
    public CompanyDetails(String companyName)
    {
        this.companyName=companyName;
    }
    
    public void showCompanyName()
    {
        System.out.println(this.companyName);
    }
}

Step 6: Create a class "Company" which would be a Composite demo class

public class Company
{

    public static void main(String[] args)
    {
        Employee d1 = new Developer("Lenin", 10);
        Employee d2 = new Developer("Chenchu", 11);
        Employee d3 = new Developer("Raja", 12);

        Employee m1 = new Manager("Rakesh", 1);


        CompanyDetails companyDetails = new CompanyDetails("XYZ");
        companyDetails.addEmployee(m1);
        companyDetails.addEmployee(d1);
        companyDetails.addEmployee(d2);
        companyDetails.addEmployee(d3);

        companyDetails.printEmployeeDetails();

    }
}