Intent

"Compose objects into tree structure to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly."

Motivation

The Composite design pattern is intended to allow you to compose objects into tree structures to represent part-whole hierarchies. This essentially means that you will be able to group components to form larger components and then use this grouping to yet again build an even larger component. One of the easiest ways to think of this is by first thinking of a blank canvas, in order for us to create our masterpiece we would first focus on drawing say a ‘rocket ship’ out of primitive shapes and then adding more and more components to this canvas until we have everything we need.

Use Cases:

Typically you will want to use the Composite pattern when: You want to represent part-whole hierarchies of objects This will essentially allow you to sub-divide larger, more complex components into smaller components. you want clients to be able to ignore the difference between compositions of objects and individual objects. Clients will treat all objects in the composite structure uniformly

UML Diagram

Composite Design Pattern Tutorial

Implementation Example:

GraphicComponent Class:

public abstract class GraphicComponent {

	public void add(GraphicComponent newGraphicComponent){
		throw new UnsupportedOperationException();
	}
	
	public void remove(GraphicComponent graphicComponent){
		throw new UnsupportedOperationException();
	}
	
	public GraphicComponent getComponent(int componentIndex){
		throw new UnsupportedOperationException();
	}
	
	public String getGraphicName(){
		throw new UnsupportedOperationException();
	}

	public void displayGraphicInfo() {
		throw new UnsupportedOperationException();
	}
	
}

Graphic Class


public class Graphic extends GraphicComponent{

	String graphicName;
	int x,y;
	
	public Graphic(String graphicName, int x, int y){
		this.graphicName = graphicName;
		this.x = x;
		this.y = y;
	}
	
	public String getGraphicName(){ 
		return graphicName;
	}
	
	public int getX(){
		return x;
	}
	
	public int getY(){
		return y;
	}
	
}

Picture Class

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


public class Picture extends GraphicComponent{

	ArrayList graphicComponents = new ArrayList();
	public String graphicGroupName;
	public String graphicGroupDescription;
	
	
	public Picture(String graphicGroupName, String graphicGroupDescription){
		this.graphicGroupName = graphicGroupName;
		this.graphicGroupDescription = graphicGroupDescription;
	}
	
	public String getGroupName(){
		return this.graphicGroupName;
	}
	
	public String getGroupDesc(){
		return this.graphicGroupDescription;
	}
	
	public void add(GraphicComponent graphicComponent){
		graphicComponents.add(graphicComponent);
	}
	
	public void remove(GraphicComponent graphicComponent){
		graphicComponents.remove(graphicComponent);
	}
	
	public GraphicComponent getComponent(int componentIndex){
		return (GraphicComponent)graphicComponents.get(componentIndex);
	}
	
	
	public void displayGraphicInfo(){
		
		System.out.println(getGroupName() + " " +
				getGroupDesc() + "\n");
		
		// Cycles through and prints any Songs or SongGroups added
		// to this SongGroups ArrayList songComponents
		
		Iterator graphicIterator = graphicComponents.iterator();
		
		while(graphicIterator.hasNext()) { 
			
			GraphicComponent graphicInfo = (GraphicComponent) graphicIterator.next();
			
			graphicInfo.displayGraphicInfo();
			
		}
		
	}
	
}

Client class

public class Client {

	public static void main(String args[]){
		GraphicComponent rocketShip = new Picture("RocketShip", "This is a Rocket");
		GraphicComponent theMoon = new Picture("The Moon", "Big ball of cheese in the sky");
		
		GraphicComponent astronaut = new Picture("Astronutz", "This dude is nuts");
		
		rocketShip.add(astronaut);
		
		GraphicComponent FullPicture = new Picture("The Entire Picture", "Contains both the rocket and the big ball of cheese");
		
		FullPicture.add(rocketShip);
		FullPicture.add(theMoon);
		
		FullPicture.displayGraphicInfo();
		
	}
	
}