Composite Design Pattern with Java
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.
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
- Component — defines the interface for objects in the composition and for accessing and managing its child components.
- Leaf — defines behavior for primitive objects in the composition. It represents leaf objects in the composition.
- 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…
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..
IntelliJ IDE is providing a nice representation on the classes. You can see it below.
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…
This is all about Composite pattern guys!
Bye Bye…