The composite pattern is a structural design pattern. This pattern is also called a partitioning pattern. This pattern explains that a group of objects will be treated as a same way as a single instance of an object. The intention of the composite pattern is to compose objects into tree hierarchies to represent the part-whole relationship.
In composite pattern, the 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 leaf in a tree does not have children. The children of a composite can be leaves or other composites.
The main benefit of composite pattern is it defines class hierarchies consisting of primitive and composite objects. It also makes provision for us to add new kind of components.
Usage
When clients use to ignore the difference between composition of objects and individual objects.
When the structure can have any level of complexity and is dynamic.
Class Diagram
Let’s take an example of the composite design pattern. First, we will declare a Greeting interface that declares 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.
package com.roytuts.designpattern.composite; public interface Greeting { void sayWelcome(); void syaGoodBye(); }
The Leaf class has a name field and implements the sayWelcome() and sayGoodbye() methods of the Greeting interface by displaying messages to the standard output.
package com.roytuts.designpattern.composite; public class Leaf implements Greeting { String name; public Leaf(String name) { this.name = name; } @Override public void sayWelcome() { System.out.println(name + " says Welcome"); } @Override public void sayGoodBye() { System.out.println(name + " says Good Bye"); } }
The Composite class implements the Greeting interface. It implements sayWelcome() and sayGoodbye() methods by calling these same methods on all of its children, which are Greetings (since they can be both Leaf objects and Composite objects, which both implement the Greeting interface).
package com.roytuts.designpattern.composite; import java.util.ArrayList; import java.util.List; public class Composite implements Greeting { List<Greeting> greetings = new ArrayList<Greeting>(); @Override public void sayWelcome() { for (Greeting greeting : greetings) { greeting.sayWelcome(); } } @Override public void sayGoodBye() { for (Greeting greeting : greetings) { greeting.sayGoodBye(); } } public void add(Greeting greeting) { greetings.add(greeting); } public void remove(Greeting greeting) { greetings.remove(greeting); } public List<Greeting> getGreetings() { return greetings; } public Greeting getGreeting(int index) { return greetings.get(index); } }
The CompositePatternTest class demonstrates the composite design pattern.
package com.roytuts.designpattern.composite; public class CompositePatternTest { /** * @param args */ public static void main(String[] args) { Leaf l1 = new Leaf("Sumit"); Leaf l2 = new Leaf("Soumen"); Leaf l3 = new Leaf("Gourab"); Leaf l4 = new Leaf("Debmalya"); Leaf l5 = new Leaf("Debabrata"); Leaf l6 = new Leaf("Liton"); Composite c1 = new Composite(); c1.add(l1); Composite c2 = new Composite(); c2.add(l2); c2.add(l3); c2.add(l4); Composite c3 = new Composite(); c3.add(l5); c3.add(l6); c2.add(c3); //c1.add(c2); c1.sayWelcome(); System.out.println(); c1.sayGoodBye(); System.out.println(); c2.sayWelcome(); System.out.println(); c2.sayGoodBye(); } }
Run the above class. You will find below output in the console.
Output
Sumit says Welcome Sumit says Good Bye Soumen says Welcome Gourab says Welcome Debmalya says Welcome Debabrata says Welcome Liton says Welcome Soumen says Good Bye Gourab says Good Bye Debmalya says Good Bye Debabrata says Good Bye Liton says Good Bye
From the above output, we can see that the composite pattern allows us to perform operations on the composites and leaves that make up a tree structure via a common interface.
That’s all. Thanks for your reading.