Composite Design Pattern with Java

Salitha Chathuranga
5 min readMay 18, 2022

--

Structural Design Patterns: Composite pattern

Hey guys! This is my 4th article on design patterns…I am looking into the theoretical aspects of design patterns. So, I thought to write about them with examples, as I understood. I’ll explain one more structural design patterns…

You can access my all design pattern related stories from here:

https://medium.com/@salithachathuranga94/list/design-patterns-0c5868220e4e

Composite pattern…

Sounds weird? No..I guess..So, as it name itself, this pattern is based o composition.

It represents a group of objects through a defined structure/hierarchy.

Actually it’s a tree structure. A composite can have a composite or a leaf.

Tree structure

As an example, we can think of a company. We have several departments. Under each department we have set of employees. It’s kind of a hierarchy.

Here we have some key things to remember from the design pattern aspect.

3 Key Concepts

  1. Component — defines the interface for objects in the composition and for accessing and managing its child components.
  2. Leaf — defines behavior for primitive objects in the composition. It represents leaf objects in the composition.
  3. Composite — stores child components and implements children derived from the component interface and manages them.

If I show this in a simple UML diagram, it will be like this…

Composite pattern basic UM diagram

As you see, Composite class it holding Component objects. So, that is the place we see the composition!

Let’s take the same company example to demonstrate this.

Our component class will be Employee interface.

Employee

public interface Employee {
void showDetails();
}

Leaves will be the below classes..Developer/QA/Manager/CEO

CEO

public class CEO implements Employee {
private final String name;
private final String dept;
private final String job;

public CEO(String name, String dept, String job) {
this.name = name;
this.dept = dept;
this.job = job;
}

@Override
public void showDetails() {
System.out.println(this);
}

@Override
public String toString() {
return "CEO{" +
"name='" + name + '\'' +
", dept='" + dept + '\'' +
", job='" + job + '\'' +
'}';
}
}

Developer

import java.util.List;

public class Developer implements Employee {
private final String name;
private final String dept;
private final String job;

public Developer(String name, String dept, String job) {
this.name = name;
this.dept = dept;
this.job = job;
}

@Override
public void showDetails() {
System.out.println(this);
}

@Override
public String toString() {
return "Developer{" +
"name='" + name + '\'' +
", dept='" + dept + '\'' +
", job='" + job + '\'' +
'}';
}
}

Manager

public class Manager implements Employee {
private final String name;
private final String dept;
private final String job;

public Manager(String name, String dept, String job) {
this.name = name;
this.dept = dept;
this.job = job;
}

@Override
public void showDetails() {
System.out.println(this);
}

@Override
public String toString() {
return "Manager{" +
"name='" + name + '\'' +
", dept='" + dept + '\'' +
", job='" + job + '\'' +
'}';
}
}

QA

public class QA implements Employee {

private final String name;
private final String dept;
private final String job;

public QA(String name, String dept, String job) {
this.name = name;
this.dept = dept;
this.job = job;
}

@Override
public void showDetails() {
System.out.println(this);
}

@Override
public String toString() {
return "QA{" +
"name='" + name + '\'' +
", dept='" + dept + '\'' +
", job='" + job + '\'' +
'}';
}
}

Now we need a Composite class which holds our employees.

CompanyDirectory

public class CompanyDirectory implements Employee {

private final List<Employee> employees;

public CompanyDirectory() {
this.employees = new ArrayList<>();
}

@Override
public void showDetails() {
for (Employee employee : employees) {
employee.showDetails();
}
}

public void addEmployee(Employee employee) {
employees.add(employee);
}

public void removeEmployee(Employee employee) {
employees.remove(employee);
}

}

Then I’m going to create a Company class which is again a Composite type and having a name property additionally.

public class Company extends CompanyDirectory {
private final String name;

public Company(String name) {
this.name = name;
}

public void showCompanyName() {
System.out.println("Company: " + name);
}
}

Classes setup is done now! It’s time to test!!! Let’s create test class…

CompositeDemo

public class CompositeDemo {

public static void main(String[] args) {

CEO ceo = new CEO("Andrew", "COM", "Chief Executive Officer");

Developer developer1 = new Developer("salitha", "ENG", "Software Engineer");
Developer developer2 = new Developer("Jhon", "ENG", "Senior Software Engineer");
QA qe1 = new QA("Tom", "ENG", "Quality Assurance Engineer");
QA qe2 = new QA("Jimmy", "ENG", "Quality Assurance Lead");

Manager manager = new Manager("Peter", "HR", "HR Manager");
Manager executive = new Manager("Derik", "HR", "Senior HR Executive");

CompanyDirectory engDepartment = new CompanyDirectory();
engDepartment.addEmployee(developer1);
engDepartment.addEmployee(developer2);
engDepartment.addEmployee(qe1);
engDepartment.addEmployee(qe2);

CompanyDirectory hrDepartment = new CompanyDirectory();
hrDepartment.addEmployee(manager);
hrDepartment.addEmployee(executive);

Company company = new Company("XYZ");
company.addEmployee(ceo);
company.addEmployee(engDepartment);
company.addEmployee(hrDepartment);
company.showCompanyName();
company.showDetails();

}

}

Output is this..

Output of example

IntelliJ IDE is providing a nice representation on the classes. You can see it below.

Composite pattern example UML diagram

Note: CEO is also just a child of Employee. It is missing in the above diagram.

If we sketch the tree hierarchy for this, it will be like this…

tree structure for the example

This is all about Composite pattern guys!

Bye Bye…

--

--

Salitha Chathuranga
Salitha Chathuranga

Written by Salitha Chathuranga

Associate Technical Lead at Sysco LABS | Senior Java Developer | Blogger

No responses yet