Composite Design Pattern

By Hikmet Cakir

Composite Design Pattern

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

  1. Declare the component interface with a list of methods that make sense for both simple and complex components.
  2. Create a leaf class to represent simple elements. A program may have multiple different leaf classes.
  3. Create a container class to represent complex elements. In this class, provide an array field for storing references to sub-elements.
  4. 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.