Compose objects into tree-like structures to represent part-whole hierarchies.
Treat individual objects and compositions uniformly.
π§ What Is the Composite Pattern?
The Composite Pattern is a structural design pattern that:
- Allows you to treat individual objects and groups of objects the same way.
- Commonly used to build tree structures (e.g., filesystems, UIs, org charts).
- Enables recursive structures using "has-a" relationships.
β Real-World Use Cases
Use Case | Description |
---|---|
π File System | Files and directories, both implement Node
|
π§βπΌ Org Chart | Employees and managers all implement Employee
|
π§± UI Component Hierarchy | Buttons, Panels, Containers implement Component
|
π§Ύ HTML/XML Elements | Tags nested inside other tags |
π§ͺ Test Suites | Individual tests and test groups run recursively |
π― Key Idea
Let clients treat leaf nodes and composite nodes uniformly via a shared interface.
π UML Diagram
+---------------------+
| Component | <<interface>>
+---------------------+
| +operation() |
+---------------------+
β²
ββββββββββββββββ΄βββββββββββββββ
βΌ βΌ
+-------------+ +----------------+
| Leaf | | Composite |
+-------------+ +----------------+
| +operation()| | - children[] |
| | | +add(Component)|
+-------------+ | +remove(Component)|
| +operation() |
+----------------+
π» Java Example β File System
Weβll design a virtual file system where:
-
File
is a Leaf -
Directory
is a Composite - Both implement
FileSystemNode
interface
β
FileSystemNode.java
(Component)
public interface FileSystemNode {
void show(String indent);
}
β
File.java
(Leaf)
public class File implements FileSystemNode {
private final String name;
public File(String name) {
this.name = name;
}
@Override
public void show(String indent) {
System.out.println(indent + "π " + name);
}
}
β
Directory.java
(Composite)
public class Directory implements FileSystemNode {
private final String name;
private final List<FileSystemNode> children = new ArrayList<>();
public Directory(String name) {
this.name = name;
}
public void add(FileSystemNode node) {
children.add(node);
}
public void remove(FileSystemNode node) {
children.remove(node);
}
@Override
public void show(String indent) {
System.out.println(indent + "π " + name);
for (FileSystemNode child : children) {
child.show(indent + " ");
}
}
}
β
Client.java
public class CompositePatternDemo {
public static void main(String[] args) {
Directory root = new Directory("root");
File file1 = new File("resume.pdf");
File file2 = new File("notes.txt");
Directory photos = new Directory("Photos");
File img1 = new File("pic1.jpg");
File img2 = new File("pic2.png");
photos.add(img1);
photos.add(img2);
root.add(file1);
root.add(file2);
root.add(photos);
root.show("");
}
}
π§ͺ Output
π root
π resume.pdf
π notes.txt
π Photos
π pic1.jpg
π pic2.png
β¨ Benefits
Benefit | Description |
---|---|
β Uniformity | Treat leaf and composite objects the same |
β Recursive composition | Build flexible, nested structures |
β Open/Closed Principle | Add new types of nodes without affecting others |
β Hierarchical navigation | Natural for tree-based data models |
β οΈ Limitations
- β Can make code harder to understand if overused
- π§© Composite structure can be too generic β use only where hierarchy is meaningful
- Requires careful traversal to avoid performance hits on large trees
π§Ύ Summary
Aspect | Details |
---|---|
Pattern Type | Structural |
Used For | Tree-like hierarchy modeling |
Design Principle | Treat part and whole uniformly |
Java Examples |
java.awt.Component , javax.swing.JComponent
|
Ideal For | File system, menus, UI trees, org charts |
π§ Interview Tip
Use Composite Pattern when the problem domain requires recursive traversal or group-leaf relationships.
Explain how it follows the Composite Principle: βClients should treat individual objects and composites uniformly.β
Top comments (0)