Overview
The Composite Design Pattern allows you to compose objects into tree structures to represent part-whole hierarchies. It enables clients to treat individual objects and compositions of objects uniformly.
Key Characteristics
- Defines a tree structure of objects where each object can be treated the same way.
- Supports recursive compositions, allowing any component to act as a container for other components.
- Promotes transparency between leaf and composite nodes.
Implementation
The following is an example of a Composite implementation in Java:
import java.util.ArrayList;
import java.util.List;
// Component
interface Employee {
void showDetails();
}
// Leaf
class Developer implements Employee {
private String name;
private String position;
public Developer(String name, String position) {
this.name = name;
this.position = position;
}
@Override
public void showDetails() {
System.out.println(name + " works as a " + position);
}
}
// Leaf
class Manager implements Employee {
private String name;
private String position;
public Manager(String name, String position) {
this.name = name;
this.position = position;
}
@Override
public void showDetails() {
System.out.println(name + " works as a " + position);
}
}
// Composite
class Directory implements Employee {
private List employees = new ArrayList<>();
public void addEmployee(Employee employee) {
employees.add(employee);
}
public void removeEmployee(Employee employee) {
employees.remove(employee);
}
@Override
public void showDetails() {
for (Employee employee : employees) {
employee.showDetails();
}
}
}
// Demo
public class CompositeDemo {
public static void main(String[] args) {
Developer dev1 = new Developer("John", "Frontend Developer");
Developer dev2 = new Developer("Jane", "Backend Developer");
Manager manager1 = new Manager("Alice", "Project Manager");
Directory directory = new Directory();
directory.addEmployee(dev1);
directory.addEmployee(dev2);
directory.addEmployee(manager1);
directory.showDetails();
}
}
When to Use
- When you need to represent part-whole hierarchies.
- When clients need to treat individual objects and compositions uniformly.
Advantages
- Simplifies client code by treating individual objects and compositions uniformly.
- Supports open-ended recursive structures.
Disadvantages
- Can make the design overly general, introducing unnecessary complexity.