DEV Community

Erwan Le Tutour
Erwan Le Tutour

Posted on

1

Composite design pattern — Java

design-pattern

Definition of Composite pattern

In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes a group of objects that are treated the same way as a single instance of the same type of object. The intent of a composite is to “compose” objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.

Where to use the Composite pattern?

When we want to implement the same interface on leaves and composites so that they are handled in the same way.

UML example

Implementation of the Composite pattern

First we need to declare the interface that will describe the behavior of our component.

package main.composite;
public interface Human {
String getName();
String getLastName();
void print();
void addChild(Human child);
void addParent(Human parent);
}

Then the implementation will have the same behavior but with some hierarchy between them.
package main.composite;
import java.util.ArrayList;
import java.util.List;
public class GrandParent implements Human{
private String name;
private String lastName;
@Override
public String getName() {
return name;
}
@Override
public String getLastName() {
return lastName;
}
public GrandParent(String name, String lastName){
this.name = name;
this.lastName = lastName;
}
@Override
public void print() {
System.out.println("==============================");
System.out.println("Name : " + getName());
System.out.println("Last name : " + getLastName());
System.out.println("Childs :");
for (Human child: childs) {
System.out.println(" - Name : " + child.getName());
}
System.out.println("==============================");
}
private List<Human> childs = new ArrayList<>();
@Override
public void addChild(Human child) {
childs.add(child);
}
@Override
public void addParent(Human parent) {
}
}
package main.composite;
import java.util.ArrayList;
import java.util.List;
public class Parent implements Human{
private String name;
private String lastName;
@Override
public String getName() {
return name;
}
@Override
public String getLastName() {
return lastName;
}
public Parent(String name, String lastName){
this.name = name;
this.lastName = lastName;
}
@Override
public void print() {
System.out.println("==============================");
System.out.println("Name : " + getName());
System.out.println("Last name : " + getLastName());
System.out.println("Parents :");
for (Human parent: grandParents) {
System.out.println(" - Name : " + parent.getName());
}
System.out.println("Childs :");
for (Human child: childs) {
System.out.println(" - Name : " + child.getName());
}
System.out.println("==============================");
}
private List<Human> childs = new ArrayList<>();
@Override
public void addChild(Human child) {
childs.add(child);
}
private List<Human> grandParents = new ArrayList<>();
@Override
public void addParent(Human parent) {
grandParents.add(parent);
}
}
view raw Parent.java hosted with ❤ by GitHub
package main.composite;
import java.util.ArrayList;
import java.util.List;
public class Child implements Human{
private String name;
private String lastName;
@Override
public String getName() {
return name;
}
@Override
public String getLastName() {
return lastName;
}
public Child(String name, String lastName){
this.name = name;
this.lastName = lastName;
}
@Override
public void print() {
System.out.println("==============================");
System.out.println("Name : " + getName());
System.out.println("Last name : " + getLastName());
System.out.println("Parents :");
for (Human parent: parents) {
System.out.println(" - Name : " + parent.getName());
}
System.out.println("==============================");
}
@Override
public void addChild(Human child) {
}
private List<Human> parents = new ArrayList<>();
@Override
public void addParent(Human parent) {
parents.add(parent);
}
}
view raw Child.java hosted with ❤ by GitHub

The only difference in these implementations are the use of the addParent() and addChild() to create the hierarchy like we can see the following example and the output it will produce.
package main.composite;
public class CompositeMain {
public static void main(String[] args) {
Child mathys = new Child("Mathys", "Le Tutour");
Parent erwan = new Parent("Erwan", "Le Tutour");
Parent amelie = new Parent("Amelie", "Le Tutour");
mathys.addParent(erwan);
mathys.addParent(amelie);
erwan.addChild(mathys);
amelie.addChild(mathys);
GrandParent philippe = new GrandParent("Philippe", "Le Tutour");
philippe.addChild(erwan);
erwan.addParent(philippe);
philippe.print();
erwan.print();
mathys.print();
}
}

==============================
Name : Philippe
Last name : Le Tutour
Childs :
- Name : Erwan
==============================
==============================
Name : Erwan
Last name : Le Tutour
Parents :
- Name : Philippe
Childs :
- Name : Mathys
==============================
==============================
Name : Mathys
Last name : Le Tutour
Parents :
- Name : Erwan
- Name : Amelie
==============================

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (2)

Collapse
 
j143 profile image
Janardhan Pulivarthi

Thanks. straightforward.

Collapse
 
erwanlt profile image
Erwan Le Tutour

thank you for your reading time, happy that this tutorial was able to help.