Java 3 min read

The Composite Design Pattern: Trees Everywhere

Master the Composite Pattern in Java. Learn how to treat individual objects and compositions uniformly using recursive tree structures.

MR

Moshiour Rahman

Advertisement

The Problem: Individual vs Groups

Imagine you are building a File System. You have File objects and Folder objects.

  • A File has a size.
  • A Folder contains Files and other Folders.

How do you calculate the size of a Folder? You need to:

  1. Sum the sizes of all the Files.
  2. Recursively sum the sizes of all child Folders.

If you treat File and Folder as completely different types, your code becomes messy with instanceof checks.

The Solution: The Composite Pattern

The Composite Pattern lets you compose objects into tree structures to represent part-whole hierarchies. It lets clients treat individual objects and compositions of objects uniformly.

Real-Life Analogy: An Organization Chart 🏢

  • Employee (Leaf): A developer with no reports.
  • Manager (Composite): Has a list of employees under them.

When you ask “What’s your team’s total salary?”, you:

  1. Employee: Returns their own salary.
  2. Manager: Sums salaries of all their reports (recursively).

The magic? Both Employee and Manager implement the same getSalary() method.

Visualizing the Pattern

Composite Pattern

Implementation

1. The Component Interface

public interface FileSystemNode {
    int getSize();
    void print(String indent);
}

2. Leaf (The Simple Object)

public class File implements FileSystemNode {
    private String name;
    private int size;

    public File(String name, int size) {
        this.name = name;
        this.size = size;
    }

    @Override
    public int getSize() {
        return size; // Just return own size
    }

    @Override
    public void print(String indent) {
        System.out.println(indent + "File: " + name + " (" + size + " bytes)");
    }
}

3. Composite (The Container)

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

public class Folder implements FileSystemNode {
    private String name;
    private List<FileSystemNode> children = new ArrayList<>();

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

    public void add(FileSystemNode node) {
        children.add(node);
    }

    @Override
    public int getSize() {
        int total = 0;
        for (FileSystemNode child : children) {
            total += child.getSize(); // Recursive!
        }
        return total;
    }

    @Override
    public void print(String indent) {
        System.out.println(indent + "Folder: " + name);
        for (FileSystemNode child : children) {
            child.print(indent + "  "); // Recursive!
        }
    }
}

Usage

FileSystemNode file1 = new File("file1.txt", 100);
FileSystemNode file2 = new File("file2.txt", 200);

Folder documents = new Folder("Documents");
documents.add(file1);
documents.add(file2);

Folder photos = new Folder("Photos");
photos.add(new File("pic1.jpg", 500));

Folder root = new Folder("Root");
root.add(documents);
root.add(photos);

System.out.println("Total size: " + root.getSize()); // 800
root.print("");

In The Wild (Real World Examples)

1. GUI Frameworks (Swing, JavaFX)

A Container (like JPanel) can hold Component objects (like JButton or other JPanel containers). Both implement Component, so you can call setVisible() on a single button or a whole panel tree.

2. AST (Abstract Syntax Trees) in Compilers

An expression like 2 + (3 * 4) is a tree:

  • + is a composite (has left and right children).
  • 2, 3, 4 are leaves (numbers).

The evaluate() method is recursive, just like our file size example.

Cheat Sheet

FeatureDetails
CategoryStructural
Problem SolvedTreating part-whole hierarchies uniformly
Key implementationRecursive structures (Tree)
ProsSimplicity (Client doesn’t need to know if it’s dealing with a leaf or composite)
ConsOverly general (Hard to restrict what children a composite can have)

Tips to Remember 🧠

  • “Matryoshka Doll Again”: Like a folder containing folders containing files.
  • “Recursion”: If you see recursive calls on children, it’s likely Composite.

Advertisement

MR

Moshiour Rahman

Software Architect & AI Engineer

Share:
MR

Moshiour Rahman

Software Architect & AI Engineer

Enterprise software architect with deep expertise in financial systems, distributed architecture, and AI-powered applications. Building large-scale systems at Fortune 500 companies. Specializing in LLM orchestration, multi-agent systems, and cloud-native solutions. I share battle-tested patterns from real enterprise projects.

Related Articles

Comments

Comments are powered by GitHub Discussions.

Configure Giscus at giscus.app to enable comments.