Structural Pattern

Composite Pattern

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions uniformly.

10 min readMedium Priority

1What is Composite Pattern?

Real-World Analogy
File System

A folder can contain files OR other folders. Whether you delete a single file or an entire folder tree, you use the same "delete" operation.

Military Hierarchy

Orders flow from generals to divisions to squads to soldiers. A command to "attack" works whether given to one soldier or an entire army.

Composite creates a tree structure where both individual objects (leaves) and groups (composites) implement the same interface. Clients don't need to know if they're working with a single item or a group.

Composite Tree Structure

Root FolderFolder AFile 1Folder BFile 2File 3File 4File 5CompositeLeaf
Both Folders (composite) and Files (leaf) implement the same Component interface.

2Implementation

Composite Pattern - File System
// ========== Component Interface ==========
interface FileSystemComponent {
    String getName();
    long getSize();
    void print(String indent);
}

// ========== Leaf ==========
class File implements FileSystemComponent {
    private String name;
    private long size;
    
    public File(String name, long size) {
        this.name = name;
        this.size = size;
    }
    
    @Override
    public String getName() { return name; }
    
    @Override
    public long getSize() { return size; }
    
    @Override
    public void print(String indent) {
        System.out.println(indent + "File: " + name + " (" + size + " bytes)");
    }
}

// ========== Composite ==========
class Folder implements FileSystemComponent {
    private String name;
    private List<FileSystemComponent> children = new ArrayList<>();
    
    public Folder(String name) {
        this.name = name;
    }
    
    public void add(FileSystemComponent component) {
        children.add(component);
    }
    
    public void remove(FileSystemComponent component) {
        children.remove(component);
    }
    
    @Override
    public String getName() { return name; }
    
    @Override
    public long getSize() {
        // Recursively calculate total size
        return children.stream()
                .mapToLong(FileSystemComponent::getSize)
                .sum();
    }
    
    @Override
    public void print(String indent) {
        System.out.println(indent + "Folder: " + name + " (" + getSize() + " bytes)");
        for (FileSystemComponent child : children) {
            child.print(indent + "  ");
        }
    }
}

// ========== Usage ==========
public class Main {
    public static void main(String[] args) {
        // Create files (leaves)
        File file1 = new File("document.txt", 100);
        File file2 = new File("image.png", 500);
        File file3 = new File("video.mp4", 2000);
        
        // Create folders (composites)
        Folder docs = new Folder("Documents");
        docs.add(file1);
        
        Folder media = new Folder("Media");
        media.add(file2);
        media.add(file3);
        
        Folder root = new Folder("Root");
        root.add(docs);
        root.add(media);
        
        // Treat uniformly - same method works for any component
        root.print("");
        System.out.println("\nTotal size: " + root.getSize() + " bytes");
    }
}
Output:
Folder: Root (2600 bytes)
  Folder: Documents (100 bytes)
    File: document.txt (100 bytes)
  Folder: Media (2500 bytes)
    File: image.png (500 bytes)
    File: video.mp4 (2000 bytes)

Total size: 2600 bytes

3Interview Follow-up Questions

Interview Follow-up Questions

Common follow-up questions interviewers ask

4Key Takeaways

1Composite lets you compose objects into tree structures.
2Clients treat leaves and composites uniformly.
3Perfect for: file systems, UI hierarchies, organization charts.
4Enables recursive operations (size, print, delete).
5Both Leaf and Composite implement the same Component interface.