Composite Design Pattern in Java

This article explains Composite design pattern in java with UML class diagram. It then takes an example scenario in java and explains it with class diagram and code.

Introduction: Composite Design Pattern is a structural design pattern among the Gang Of Four(GOF) Design PatternsArticle on GOF Patterns & their types. Being a structural design pattern, the Composite pattern deals with how the classes are composed to together to fulfill the functional objectives.

What is Composite Design Pattern
Composite Design pattern is ideal for designing a system where part-whole hierarchies exist, and where the part and the whole components are to be treated in the system uniformly.
Composite design pattern treats both the parts and the whole in the same way. This is very beneficial for handling hierarchical part-whole hierarchies which are recursive in nature.
Consider a binary tree. The left sub-tree and right sub-tree are themselves full-fledged binary trees. Traversals of these trees is recursive in nature due to this part-whole similarity.
Another ubiquitous example is a UML editor, every element of the diagram is treated(drawn) in the editor the same way as the whole UML diagram.

Scenarios in which Composite Design Pattern can be used
Given below are the conditions which together must be applicable to justify the use of Composite pattern while creating a product –

  1. Part-whole hierarchy exists: The system’s objects are related in a part-whole hierarchy i.e they have multiple parts being composed together to form an aggregate whole.
  2. Same treatment required for part and whole objects: The system treats the objects representing the part and the whole in the same way as it processes them. Considering a hierarchy such as a binary tree where lowest level nodes point to the root of the sub-tree. At the next level multiple such sub-trees now become parts of the next level sub-tree’s root. So, as we move up whole objects come together as parts of the next level whole. This is hierarchical part-whole relationship. Since, the role the same individual node plays changes from part to whole – we inherently need to treat the node which plays both the roles the same way aiding in their recursive traversal.

Class Diagram for Composite Design Pattern

Composite Design Pattern Class Diagram

Explanation of Composite Design Pattern’s Class Diagram

  • Leaf class represents the leaf node in a part-whole hierarchy.I.e. leaf nodes are those which do not have any children and typically play the role of part in part-whole hierarchy.
  • Composite represents the aggregate of Components i.e. the whole side of the relationship. It holds an aggregate of Components\parts and its itself a Component. This results in a recursive relationship as the whole is composed of parts which themselves can hold their own parts.
  • Component is the common base class for the Leaf and the Composite. This common base class results in the similarity between part and whole components. They, essentially, are now of the same type. And hence, the system treats them equally.
  • Client uses this part-whole hierarchy to get the desired outcome from the system.

Composite Design Pattern in Java – Class Diagram

Composite Design Pattern in Java Class Diagram

Code for the classes shown in Java Example’s Class Diagram

Employee.java
import java.util.ArrayList;
import java.util.List;
import javax.naming.OperationNotSupportedException;
public class Employee {
 protected  String name;
 protected List<Employee> reportees;
 public void printName(){
  System.out.println("Employee Name is:"+ name);
 }
 public void addReportee(Employee emp) throws OperationNotSupportedException{
  if(reportees==null){
   reportees=new ArrayList<Employee>();
  }
  reportees.add(emp);
 }
 public void removeReportee(Employee emp)throws OperationNotSupportedException{
  reportees.remove(emp);
 }
 public List<Employee> getReportees()throws OperationNotSupportedException{
  return this.reportees;
 }
 //getter & setter for variable 'name'
}
Manager.java
public class Manager extends Employee{
 public void printName(){
  //prints own name
  System.out.println("Manager\n-------------");super.printName();
  //prints all reportees names
  System.out.println("Reportees\n-------------");
  reportees.forEach(employee -> employee.printName());
 }
}
Developer.java
import java.util.List;
import javax.naming.OperationNotSupportedException;
public class Developer extends Employee{
 public void addReportee(Employee emp)throws OperationNotSupportedException{
  throw new OperationNotSupportedException();
 }
 public void removeReportee(Employee emp)throws OperationNotSupportedException{
  throw new OperationNotSupportedException();
 }
 public List<Employee> getReportees()throws OperationNotSupportedException{
  throw new OperationNotSupportedException();
 }
}
HRClient.java (with the main() method)
import javax.naming.OperationNotSupportedException;
public class HRClient {
 public static void main(String[] args) {
  Developer dev1 = new Developer();
  Developer dev2 = new Developer();
  Developer dev3 = new Developer();
  dev1.setName("tom hardy");
  dev2.setName("dick tracey");
  dev3.setName("harry ford");
  Manager manager = new Manager();
  manager.setName("Mike Mitchel");
  try {
   manager.addReportee(dev1);
   manager.addReportee(dev2);
   manager.addReportee(dev3);
  }catch (OperationNotSupportedException onse) {
   onse.printStackTrace();
  }
   manager.printName();
 }
}
 Output on running HRClient.java
Manager
————-
Employee Name is:Mike Mitchel
Reportees
————-
Employee Name is:tom hardy
Employee Name is:dick tracey
Employee Name is:harry ford

Explanation of Java Example’s Class Diagram & Code
The Java class diagram above depicts Composite Design pattern implemented for a Manager-Developer hierarchy. Lets quickly go through whats there in Java’s example’s class diagram & corresponding code –

  • Employee class represents the component, or the commonality, between all objects in the system. All individuals working in a company are employees regardless of their position in the hierarchy.
  • Manager is the composite i.e. he heads a team of developers who report to him.
  • Developer is the leaf node in the hierarchy i.e. he doesn’t have any reportees.
  • HRClient needs to print the names of all managers and their employees.
  • In the main() method of HRClient the employee’s printName() method is invoked which internally prints all his reportee employee’s names as well.
  • While printing the Manager and his Developer reportees’ printName() method is called which is there in the Employee base class. Thus both the manager(whole) and his developers(parts) are treated the same way in the system. This is what the Composite Pattern also mandates.

Summary
In the above tutorial we understood what is Composite design pattern and the main scenarios in which it is applicable. We then looked at the UML class diagram for Composite Design Pattern & its explanation, a Java Use Case implementing Composite pattern with its class diagram and code for the classes shown in the class diagram, followed by explanation of both the class diagram & code. This concludes the tutorial on Composite design pattern.

 

Digiprove sealCopyright © 2014-2016 JavaBrahman.com, all rights reserved.