The pattern organizes objects into a tree structure, where leaf objects represent individual elements and composite objects contain one or more child components.
Since both expose the same interface, clients can interact with them without distinguishing between a single object and a collection of objects.
This simplifies client code and makes it easy to build recursive object hierarchies.
The Composite Pattern is commonly used to represent file systems, organization hierarchies, UI component trees, menus, and document object models (DOM).
Structure
The Composite Pattern consists of the following participants.1. The Component defines the common interface for both leaf and composite objects.
2. The Leaf represents an individual object with no children.
3. The Composite maintains child components and delegates operations to them.
4. The Client interacts with all objects through the common component interface.

Java Implementation
Suppose an application manages a file system where folders can contain both files and other folders. The client should be able to calculate the total size of any folder regardless of how deeply nested its contents are.Create the component interface.
public interface FileSystemComponent {
int getSize();
}
Create the leaf class.
public class File implements FileSystemComponent {
private final String name;
private final int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public int getSize() {
return size;
}
}
Create the composite class.
import java.util.ArrayList;
import java.util.List;
public class Folder implements FileSystemComponent {
private final String name;
private final List<FileSystemComponent> children =
new ArrayList<>();
public Folder(String name) {
this.name = name;
}
public void add(FileSystemComponent component) {
children.add(component);
}
@Override
public int getSize() {
int totalSize = 0;
for (FileSystemComponent component : children) {
totalSize += component.getSize();
}
return totalSize;
}
}
The client creates the file hierarchy.
public class Main {
public static void main(String[] args) {
Folder root = new Folder("Root");
root.add(new File("resume.pdf", 200));
root.add(new File("photo.jpg", 500));
Folder documents = new Folder("Documents");
documents.add(new File("report.docx", 300));
documents.add(new File("invoice.pdf", 150));
root.add(documents);
System.out.println(root.getSize());
}
}
Output:
1150
How It Works?
The client works only with the FileSystemComponent interface and does not need to distinguish between files and folders.A File is a leaf object that simply returns its own size. A Folder is a composite object that stores multiple child components, which may themselves be files or other folders.
When the client invokes getSize() on a folder, the folder recursively calls getSize() on each of its children and aggregates the results.
Because both files and folders implement the same interface, nested directory structures of any depth can be processed using identical client code.
Advantages
1. It allows individual objects and collections to be treated uniformly.2. It simplifies client code by exposing a common interface.
3. Complex tree structures can be processed recursively.
4. New component types can be introduced without changing client code.
Disadvantages
1. Restricting which components can contain children may become difficult.2. Recursive operations may affect performance for very large hierarchies.
3. The common interface may expose operations that are not meaningful for leaf objects.
JDK Examples
The Composite Pattern appears throughout the Java ecosystem.1. The java.awt.Container class can contain multiple Component objects, allowing nested user interface hierarchies.
2. The javax.swing.JComponent hierarchy uses the Composite Pattern to build complex Swing user interfaces from nested components.
Summary
The Composite Pattern organizes objects into tree structures so that individual objects and groups of objects can be treated uniformly.By providing a common interface for both leaf and composite objects, the pattern simplifies recursive processing and makes hierarchical object structures easier to build, extend, and maintain.