All 15 Design Patterns in Java questions
More in Design Patterns in Java
Advertisement
Back to results for “File System”
Java › Design Patterns in Java

How would you implement the Composite pattern to treat individual objects and groups of objects uniformly, such as a file system with files and directories?

Intermediate

Answer

Composite defines a common interface shared by both individual ("leaf") objects and composite ("container") objects that hold collections of the same interface type, letting client code treat a single object and a tree of nested objects uniformly through that shared interface -- a composite's operations (like calculating total size) typically recurse into its children, naturally handling arbitrarily deep nesting without the calling code needing to know whether it's dealing with a single leaf or an entire subtree.
public interface FileSystemNode { long getSize(); }

class File implements FileSystemNode {
    private final long size;
    public File(long size) { this.size = size; }
    public long getSize() { return size; }
}

class Directory implements FileSystemNode {
    private final List<FileSystemNode> children = new ArrayList<>();
    public void add(FileSystemNode node) { children.add(node); }
    public long getSize() {
        return children.stream().mapToLong(FileSystemNode::getSize).sum();  // recurses uniformly
    }
}
Real-world example A file system browser calculates the total size of a deeply nested directory tree by calling getSize() on the top-level Directory, which transparently recurses through every nested File and Directory via the shared FileSystemNode interface, without the calling code needing any special-case logic for files versus directories.

Common follow-ups: How does the Composite pattern handle operations that only make sense for one type (leaf or composite) but not the other?;What's the performance consideration of a Composite structure that's extremely deeply nested?