Composite is a structural design pattern that composes objects into tree structures and work with these structures as if they were individual objects.
We often see small pieces are combined to create a composite. Additionally, these small pieces and composite structure are wanted to use in together. In this situations, we have to manage to relationship with between small pieces and composite piece. There is a complexity in here and we can use the Composite to manage this complexity.
How to Implement
- Declare the component interface with a list of methods that make sense for both simple and complex components.
- Create a leaf class to represent simple elements. A program may have multiple different leaf classes.
- Create a container class to represent complex elements. In this class, provide an array field for storing references to sub-elements.
- Define the methods for adding and removal of child elements in the container.
Example Implementation
I want to build a hierarchical structure of meals in a restaurant. Additionally, I want to explain uncertain expressions like leaf, component and container via example implementation.
import java.math.BigDecimal;
public abstract class Meal {
protected String name;
protected BigDecimal price;
public abstract void eat();
}
Meal class is our Base Component. I defined it as an Abstract class but it can be defined as a Interface. Additionally, this is a base component for all the objects in the composition.
import java.math.BigDecimal;
public class Hamburger extends Meal {
public Hamburger(String name, BigDecimal price) {
this.name = name;
this.price = price;
}
@Override
public void eat() {
System.out.println(name + " which price is " + price + " was eaten");
}
}
import java.math.BigDecimal;
public class Pizza extends Meal {
public Pizza(String name, BigDecimal price) {
this.name = name;
this.price = price;
}
@Override
public void eat() {
System.out.println(name + " which price is " + price + " was eaten");
}
}
Hamburger and pizza are our leafs. Leafs shows default behaviour of our base component and It mustn’t contain a reference to the other objects.
import java.util.ArrayList;
import java.util.List;
public class Package extends Meal {
private final List<Meal> meals = new ArrayList<>();
public void addMeal(Meal meal) {
meals.add(meal);
}
public void removeMeal(Meal meal) {
meals.remove(meal);
}
public List<Meal> getMeals() {
return meals;
}
@Override
public void eat() {
meals.forEach(meal -> System.out.println(meal.name + " which price is " + meal.price + " was eaten"));
}
}
Finally, Package class has leaf elements and is a container. It implements the base component methods and defines the child related operations.
I shared the codes I explained and more in GitHub. Additionally, certainly I recommend that you should practice with this structures. I coded these structures and these structures’ some test scenarios. You can check out to repository.
I used various resource for prepare this essay. I indicated in following. You can check out.
- https://www.baeldung.com/java-composite-pattern
- https://refactoring.guru/design-patterns/composite
- https://www.geeksforgeeks.org/composite-design-pattern/