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

interface FileSystemComponent {
    void showDetails();
}

class File implements FileSystemComponent {
    private String name;

    File(String name) { this.name = name; }

    public void showDetails() {
        System.out.println("File: " + name);
    }
}

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

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

    void add(FileSystemComponent component) {
        children.add(component);
    }

    void remove(FileSystemComponent component) {
        children.remove(component);
    }

    public void showDetails() {
        System.out.println("Folder: " + name);
        for (FileSystemComponent child : children) {
            child.showDetails();
        }
    }
}

public static void main(String[] args) {
    File file1 = new File("file1.txt");
    File file2 = new File("file2.txt");

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

    Folder root = new Folder("Root");
    root.add(folder);
    root.showDetails();
}
Back to Design Patterns
Structural Design Pattern

Composite

The Composite pattern composes objects into tree structures to represent part-whole hierarchies. It lets clients treat individual objects and compositions of objects uniformly. By defining a common interface for both leaf and composite nodes, the pattern simplifies client code and makes it easy to add new component types.