- What is It?
- Where and Why do We Use It?
- Key Components
- Principle Method
- Examples of Real-World Scenario
- Code without Pattern
- Code with Pattern
- Use cases of
- Advantages & Disadvantages
The Composite Design Pattern is like a tree structure. It lets you work with a group of objects in the same way you work with a single object. For example, you can treat a folder (which contains files) and a single file as the same thing. It’s part of the structural design patterns family, which deals with organizing classes and objects.
-
Where:
- When dealing with hierarchical data structures like file systems, organization charts, or UI components (buttons, panels, etc.).
-
Why?
- To treat individual objects (leaves) and groups of objects (composites) uniformly.
- To simplify client code because you don’t need to worry about whether you’re working with a single item or a group.
- Component: An abstract interface that defines common methods for both individual and composite objects.
- Leaf: Represents individual objects in the structure (e.g., a single file).
- Composite: Represents groups of objects that can include both leaves and other composites (e.g., a folder containing files or subfolders).
- Client: Uses the objects via the component interface without worrying about their type.
Recursive Composition: The Composite design pattern allows the client to treat individual objects and compositions of objects uniformly by making the composite hold a collection of components.
- File System: A folder can contain files or other folders.
- Company Hierarchy: A manager can manage individual employees or other managers.
- UI Components: A panel (composite) can contain buttons, text fields, and other panels.
import java.util.ArrayList;
import java.util.List;
// A basic file system structure without Composite Pattern
class File {
private String name;
public File(String name) {
this.name = name;
}
public void display() {
System.out.println("File: " + name);
}
}
class Folder {
private String name;
private List<File> files = new ArrayList<>();
public Folder(String name) {
this.name = name;
}
public void addFile(File file) {
files.add(file);
}
public void display() {
System.out.println("Folder: " + name);
for (File file : files) {
file.display();
}
}
}
// Client
public class WithoutComposite {
public static void main(String[] args) {
File file1 = new File("File1.txt");
File file2 = new File("File2.txt");
Folder folder = new Folder("Documents");
folder.addFile(file1);
folder.addFile(file2);
folder.display();
}
}
OUTPUT:
Folder: Documents
File: File1.txt
File: File2.txt
1. Cannot treat files and folders uniformly.
2. Adding subfolders within folders requires additional methods, increasing complexity.
import java.util.ArrayList;
import java.util.List;
// Step 1: Define Component (Common Interface)
// Component
interface FileSystem {
void display();
}
// Step 2: Define Leaf (File)
// Leaf
class File implements FileSystem {
private String name;
public File(String name) {
this.name = name;
}
@Override
public void display() {
System.out.println("File: " + name);
}
}
// Step 3: Define Composite (Folder)
// Composite
class Folder implements FileSystem {
private String name;
private List<FileSystem> children = new ArrayList<>();
public Folder(String name) {
this.name = name;
}
public void add(FileSystem component) {
children.add(component);
}
@Override
public void display() {
System.out.println("Folder: " + name);
for (FileSystem component : children) {
component.display();
}
}
}
// Step 4: Use the Composite Pattern
// Client
public class WithComposite {
public static void main(String[] args) {
// Create files
FileSystem file1 = new File("File1.txt");
FileSystem file2 = new File("File2.txt");
FileSystem file3 = new File("File3.txt");
// Create folders
Folder documents = new Folder("Documents");
Folder images = new Folder("Images");
// Build the hierarchy
documents.add(file1);
documents.add(file2);
images.add(file3);
Folder root = new Folder("Root");
root.add(documents);
root.add(images);
// Display structure
root.display();
}
}
OUTPUT:
Folder: Root
Folder: Documents
File: File1.txt
File: File2.txt
Folder: Images
File: File3.txt
- File Systems (folders and files).
- Organization structures (managers and employees).
- UI components (nested panels, buttons, text fields).
1. Simplifies Code: Treats individual objects and composites uniformly.
2. Scalability: Easy to add new types of components.
3. Extensibility: Flexible structure for recursive compositions.
1. Overhead: Adds complexity for simple structures.
2. Tight Coupling: Component classes are tightly connected.