Composite Pattern

Composite Pattern is one of the structural design pattern

In this pattern, we will have a tree structure hierarchy of classes and common operation will be performed on each class in the hierarchy.

Node in the hierarchy is a class which will have children

Node class is also called as “Composite” class

Leaf in the hierarchy is a class which does not have children.

Both leaf class and the composite class share a common interface which defines the common operations that can be performed on both leaves and composites.

This Pattern is used to perform common operations on all the classes in the tree hierarchy

Composite Pattern pattern mainly consists of 4 parts


1) Component

2) Leaf

3) Composite/Node

4) Client

Composite_Pattern-class_diagram

Component :
An interface which defines common methods for leaf and composites.

Leaf :
Implements component interface by defining the behaviour of elements in the composition

Composite :
It contains all the leaf objects and invoke the operations on each leaf object

Client :
The one who uses this composition through component interface

Let’s see how we can implement this pattern

Step 1

Create a node class/interface, which is a parent for all leaf classes

  1. package com.kb.composite;
  2.  
  3. public interface AbstractOrder {
  4.     public void calculateTotal();
  5.  
  6. }
package com.kb.composite;

public interface AbstractOrder {
	public void calculateTotal();

}

Step 2

Create leaf classes which becomes the children of Node class/interface

  1. package com.kb.composite;
  2.  
  3. public class Cart implements AbstractOrder{
  4.  
  5.     @Override
  6.     public void calculateTotal() {
  7.         System.out.println("Cart total calculated");
  8.        
  9.     }
  10.  
  11. }
package com.kb.composite;

public class Cart implements AbstractOrder{

	@Override
	public void calculateTotal() {
		System.out.println("Cart total calculated");
		
	}

}

  1. package com.kb.composite;
  2.  
  3. public class Order implements AbstractOrder{
  4.  
  5.     @Override
  6.     public void calculateTotal() {
  7.         System.out.println("Order total calculated");
  8.        
  9.     }
  10.  
  11. }
package com.kb.composite;

public class Order implements AbstractOrder{

	@Override
	public void calculateTotal() {
		System.out.println("Order total calculated");
		
	}

}

Step 3

Create a composite class which holds all the leaf classes and invokes operation on them

  1. package com.kb.composite;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. public class AbstractOrderComposite implements AbstractOrder {
  7.     // collection of AbstractOrder
  8.     private List<AbstractOrder> abstractOrderList = new ArrayList<AbstractOrder>();
  9.  
  10.     @Override
  11.     public void calculateTotal() {
  12.         for (AbstractOrder abstractOrder : abstractOrderList) {
  13.             abstractOrder.calculateTotal();
  14.  
  15.         }
  16.  
  17.     }
  18.  
  19.     // adding abstractOrder to AbstractOrderComposite
  20.     public void add(AbstractOrder abstractOrder) {
  21.         abstractOrderList.add(abstractOrder);
  22.     }
  23.  
  24.     // removing abstractOrder from AbstractOrderComposite
  25.     public void remove(AbstractOrder abstractOrder) {
  26.         abstractOrderList.remove(abstractOrder);
  27.     }
  28.  
  29.     // removing all the abstractOrders in AbstractOrderComposite
  30.     public void clear() {
  31.         System.out.println("Clearing all the elements from composite class");
  32.         abstractOrderList.clear();
  33.     }
  34.  
  35. }
package com.kb.composite;

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

public class AbstractOrderComposite implements AbstractOrder {
	// collection of AbstractOrder
	private List<AbstractOrder> abstractOrderList = new ArrayList<AbstractOrder>();

	@Override
	public void calculateTotal() {
		for (AbstractOrder abstractOrder : abstractOrderList) {
			abstractOrder.calculateTotal();

		}

	}

	// adding abstractOrder to AbstractOrderComposite
	public void add(AbstractOrder abstractOrder) {
		abstractOrderList.add(abstractOrder);
	}

	// removing abstractOrder from AbstractOrderComposite
	public void remove(AbstractOrder abstractOrder) {
		abstractOrderList.remove(abstractOrder);
	}

	// removing all the abstractOrders in AbstractOrderComposite
	public void clear() {
		System.out.println("Clearing all the elements from composite class");
		abstractOrderList.clear();
	}

}

Step 4

Create a client class which uses this pattern

  1. package com.kb.composite;
  2.  
  3. public class Client {
  4.  
  5.     public static void main(String[] args) {
  6.         AbstractOrder cart = new Cart();
  7.         AbstractOrder order = new Order();
  8.        
  9.         AbstractOrderComposite abstractOrderComposite  = new AbstractOrderComposite();
  10.         abstractOrderComposite.add(cart);
  11.         abstractOrderComposite.add(order);
  12.        
  13.         abstractOrderComposite.calculateTotal();
  14.        
  15.         //This will remove all elements which composite class holds
  16.         abstractOrderComposite.clear();
  17.  
  18.     }
  19.  
  20. }
package com.kb.composite;

public class Client {

	public static void main(String[] args) {
		AbstractOrder cart = new Cart();
		AbstractOrder order = new Order();
		
		AbstractOrderComposite abstractOrderComposite  = new AbstractOrderComposite();
		abstractOrderComposite.add(cart);
		abstractOrderComposite.add(order);
		
		abstractOrderComposite.calculateTotal();
		
		//This will remove all elements which composite class holds
		abstractOrderComposite.clear();

	}

}


Now if we observe abstractOrderComposite.calculateTotal(); line in the above class

We can see that, this single line is calling methods of each leaf class as operation is same for all the leaf class but implementation is different for each leaf class.


Applications of Composite Pattern

This pattern is already used in many places within java itself like XML parsing and in some of the collection methods like
List#addAll(Collection), Set#addAll(Collection) etc

Advantages of Composite Pattern

Clients use the Component class interface to interact with objects in the composite structure
Calling a Composite forwards, the request to its child components

Disadvantages of Composite Pattern

Leaf classes have to create some methods which has to empty in some cases
Once tree structure is defined, the composite pattern makes the tree overly general

When to use Composite Pattern ?

1. When we need to treat all objects in the composite structure uniformly.
2. When the group of objects should behave as the single object.

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on