Structural Patterns  «Prev 

Composite Pattern Code in Java

The Composite design patten allows you to have a tree structure and ask each node in the tree structure to perform a task.
Let us take a real life example from an organization. It contains general managers and under general managers there can be managers, under managers there can be developers.
Now you can set a tree structure and ask each node to perform a common operation like getSalary().. The following statement is extracted from the Gang of Four:
"Compose objects into tree structure to represent part-whole hierarchies.Composite lets client treat individual objects and compositions of objects uniformly."
Composite design pattern treats each node in two ways:
  1. Composite or
  2. leaf.
Composite means it can have other objects below it.leaf means it has no objects below it.

When to use it:

  1. You want to represent part-whole hierachies of objects.
  2. You want a client[1] to be able to ignore differences between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly.

Elements:

Component

  1. Declares an interface for objects in the composition.
  2. Implements the default behaviour for the interface common to all classes as appropriate.
  3. Declares an interface for accessing and managing its child components.

Leaf

  1. Represents leaf objects in the composition. A leaf has no children.
  2. Defines behaviour for primitive objects in the composition.

Composite

  1. Defines behaviour for components having children.
  2. Stores child components.
  3. Implements child related operations in the component interface.

Workflow

Client uses the component class interface to interact with objects in the composition structure. If the recipient is a leaf, then the request is handled directly. If the recipient is a composite, then it usually forwards the request to its child components, possibly performing additional operations before and after forwarding.
Our example consist of following elements.
  1. Manager(Composite)
  2. Developer(Leaf)
  3. Employee(Component)

Java code for all above classes: First we will create component inrteface.It represents object in composition. It has all common operation that will be applicable to both manager and developer.

package com.java.structural.composite;

public interface Employee {
  public void add(Employee employee);
  public void remove(Employee employee);
  public Employee getChild(int i);
  public String getName();
  public double getSalary();
  public void print();
}

Now we will create the manager class which represents the composite pattern. Key point here is that all common method delegates its operations to child objects.It has method to access and modify its children.

 
package com.java.structural.composite;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Manager implements Employee{
 private String name;
 private double salary;

 public Manager(String name,double salary){
  this.name = name;
  this.salary = salary;
 }
 
 List <Employee> employees = new ArrayList <Employee>();
 public void add(Employee employee) {
    employees.add(employee);
 }

 public Employee getChild(int i) {
  return employees.get(i);
 }

 public String getName() {
  return name;
 }

 public double getSalary() {
  return salary;
 }

 public void print() {
 System.out.println("-------------");
 System.out.println("Name ="+getName());
 System.out.println("Salary ="+getSalary());
 System.out.println("-------------");
 
 Iterator<Employee> employeeIterator = employees.iterator();
   while(employeeIterator.hasNext()){
    Employee employee = employeeIterator.next();
    employee.print();
   }
 }

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

We will create a developer class which designates a leaf node so all operations related to accessing children will be empty because it has no children.

package com.java.structural.composite;

public class Developer implements Employee{

 private String name;
 private double salary;
 public Developer(String name,double salary){
  this.name = name;
  this.salary = salary;
 }
 public void add(Employee employee) {
  /* this is leaf node so this method 
  is not applicable to this class. */
 }

 public Employee getChild(int i) {
  /* this is leaf node so this method 
  is not applicable to this class. */
  return null;
 }

 public String getName() {
   return name;
 }

 public double getSalary() {
   return salary;
 }

 public void print() {
  System.out.println("-------------");
  System.out.println("Name = "+getName());
  System.out.println("Salary = "+getSalary());
  System.out.println("-------------");
 }

 public void remove(Employee employee) {
  /* this is leaf node so this method 
  is not applicable to this class. */
 }
}

The Driver program that contains main method
package com.java.structural.composite;
public class CompositeDriver {
 public static void main(String[] args) {
  Employee emp1=new Developer("Carl Gauss", 1100);
  Employee emp2=new Developer("Isaac Newton", 1700);
  Employee manager1=new Manager("Bernhard Riemann",1900);
  manager1.add(emp1);
  manager1.add(emp2);
  Employee emp3=new Developer("Joseph Lagrange", 2300);
  Manager generalManager=new Manager("Augustin Cauchy", 2900);
  generalManager.add(emp3);
  generalManager.add(manager1);
  generalManager.print();
 }
}
/* 
Program output 
-------------
Name =Augustin Cauchy
Salary =2900.0
-------------
-------------
Name =Joseph Lagrange
Salary =2300.0
-------------
-------------
Name =Bernhard Riemann
Salary =1900.0
-------------
-------------
Name =Carl Gauss
Salary =1100.0
-------------
-------------
Name =Isaac Newton
Salary =1700.0
-------------
*/

[1]Client: manipulates objects in the composition through the component interface.