Composite Pattern
Author: Deron Eriksson
Description: This Java tutorial describes the composite pattern, a structural design pattern.
Tutorial created using: Windows Vista || JDK 1.6.0_11 || Eclipse JEE Ganymede SR1 (Eclipse 3.4.1)


Page:    1 2 >

The composite pattern is a structural design pattern. In the composite pattern, a tree structure exists where identical operations can be performed on leaves and nodes. A node in a tree is a class that can have children. A node class is a 'composite' class. A leaf in a tree is a 'primitive' class that does not have children. The children of a composite can be leaves or other composites.

The leaf class and the composite class share a common 'component' interface that defines the common operations that can be performed on leaves and composites. When an operation on a composite is performed, this operation is performed on all children of the composite, whether they are leaves or composites. Thus, the composite pattern can be used to perform common operations on the objects that compose a tree.

The Gang of Four description of the composite pattern defines a client's interaction with the tree struture via a Component interface, where this interface includes the common operations on the composite and leaf classes, and the add/remove/get operations on the composites of the tree. This seems slightly awkward since a leaf does not implement the add/remove/get operations. In my opinion, in JavaSW it makes more sense to define the common leaf/composite operations on a Component interface, but to put the add/remove/get composite operations in a separate interface or to simply implement them in the composite class.

Now we'll look at an example of the composite pattern. First, we'll declare a Component interface that declares the operations that are common for the composite class and the leaf class. This allows us to perform operations on composites and leaves using one standard interface.

Component.java

package com.cakes;

public interface Component {

	public void sayHello();

	public void sayGoodbye();

}

The Leaf class has a name field and implements the sayHello() and sayGoodbye() methods of the Component interface by outputting messages to standard output.

Leaf.java

package com.cakes;

public class Leaf implements Component {

	String name;

	public Leaf(String name) {
		this.name = name;
	}

	@Override
	public void sayHello() {
		System.out.println(name + " leaf says hello");
	}

	@Override
	public void sayGoodbye() {
		System.out.println(name + " leaf says goodbye");
	}

}

The Composite class implements the Component interface. It implements the sayHello() and sayGoodbye() methods by calling these same methods on all of its children, which are Components (since they can be both Leaf objects and Composite objects, which both implement the Component interface).

Composite.java

package com.cakes;

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

public class Composite implements Component {

	List<Component> components = new ArrayList<Component>();

	@Override
	public void sayHello() {
		for (Component component : components) {
			component.sayHello();
		}
	}

	@Override
	public void sayGoodbye() {
		for (Component component : components) {
			component.sayGoodbye();
		}
	}

	public void add(Component component) {
		components.add(component);
	}

	public void remove(Component component) {
		components.remove(component);
	}

	public List<Component> getComponents() {
		return components;
	}

	public Component getComponent(int index) {
		return components.get(index);
	}

}

(Continued on page 2)

Page:    1 2 >


Related Tutorials: