Day 9: Composite Pattern — Building Tree-like Structures in Your Code

Sourabh Kumar
2 min readJul 25, 2024

--

Introduction

Welcome to day 9 of our 30-Day Design Pattern Challenge! Today, we’ll dive into the Composite Pattern, a structural design pattern that lets you compose objects into tree-like structures to represent part-whole hierarchies. This pattern allows you to treat individual objects and compositions of objects uniformly.

What is it?

The Composite Pattern provides a way to represent hierarchical structures where both individual objects (leaves) and compositions of objects (composites) can be treated uniformly. This means you can apply the same operations to a single object or a group of objects without differentiating between them.

Problem

Imagine you’re building a file system. You have files and directories. A directory can contain files and other directories. You want to perform operations like listing contents or calculating size on both files and directories consistently.

Solution

The Composite Pattern suggests creating a common interface for both files and directories. This interface defines operations that both can perform. Concrete File classes implement these operations for individual files, while concrete Directory classes implement them for directories, including managing child components (files or directories).

Class Diagram

The class diagram involves these entities:

  • Component (File or Directory interface): Declares the interface for objects in the composition.
  • Leaf (File): Defines behavior for primitive objects in the composition.
  • Composite (Directory): Stores child components and implements child-related operations.
Class Diagram

Example

interface File {
void listContents();
int getSize();
}

class SimpleFile implements File {
// ...
@Override
public void listContents() {
// List file contents
}
@Override
public int getSize() {
// Return file size
}
}

class Directory implements File {
private List<File> files = new ArrayList<>();
public void addFile(File file) {
files.add(file);
}
@Override
public void listContents() {
for (File file : files) {
file.listContents();
}
}
@Override
public int getSize() {
int totalSize = 0;
for (File file : files) {
totalSize += file.getSize();
}
return totalSize;
}
}

Benefits

  • Treats individual objects and compositions uniformly.
  • Simplifies client code.
  • Makes it easier to add new components.

Disadvantages

  • Can introduce complexity for simple scenarios.
  • Might require careful consideration of the component interface.

When to Use

  • When you need to represent part-whole hierarchies.
  • When you want to treat individual objects and compositions uniformly.
  • When you expect the structure to change dynamically.

When Not to Use

  • When the hierarchy is static and well-defined.
  • When the performance overhead of the Composite Pattern is significant.

Conclusion

The Composite Pattern is a valuable tool for managing hierarchical structures. By treating individual objects and compositions consistently, you can simplify your code and make it more flexible.

Join us tomorrow for Day 10, where we’ll explore the Decorator Pattern!

Feel free to leave comments or questions below. If you enjoyed this blog, consider giving it a clap 👏!

--

--

Sourabh Kumar
Sourabh Kumar

Written by Sourabh Kumar

Software Developer. Tech Enthusiast. Innovative Solver.

No responses yet