πŸ“ What You’ll Learn

  • What the Composite Pattern is
  • Why and when to use it
  • How to implement it in Java
  • Real-world use cases and analogies
  • Pitfalls and best practices

πŸ” What Is the Composite Pattern?

The Composite Pattern lets you compose objects into tree structures to represent part-whole hierarchies. It lets clients treat individual objects and groups of objects uniformly.

β€œLeaf and branch β€” treated the same way.”

🧩 When to Use It

Use the Composite Pattern when:

  • You need to represent hierarchical structures (e.g., files, UI components)
  • You want to treat individual objects and composites uniformly
  • Operations on elements should work the same way for both simple and complex structures

🧱 Java Implementation

🧩 Step 1: Create a Component Interface

public interface Employee {
    void showDetails();
}

πŸ‘€ Step 2: Leaf Classes

public class Developer implements Employee {
    private String name;
    private String role;

    public Developer(String name, String role) {
        this.name = name;
        this.role = role;
    }

    public void showDetails() {
        System.out.println(name + " (" + role + ")");
    }
}
public class Designer implements Employee {
    private String name;

    public Designer(String name) {
        this.name = name;
    }

    public void showDetails() {
        System.out.println(name + " (Designer)");
    }
}

🌿 Step 3: Composite Class

import java.util.ArrayList;
import java.util.List;

public class Manager implements Employee {
    private String name;
    private List<Employee> team = new ArrayList<>();

    public Manager(String name) {
        this.name = name;
    }

    public void addEmployee(Employee e) {
        team.add(e);
    }

    public void removeEmployee(Employee e) {
        team.remove(e);
    }

    public void showDetails() {
        System.out.println(name + " (Manager)");
        for (Employee e : team) {
            e.showDetails();
        }
    }
}

βœ… Usage

Employee dev1 = new Developer("Alice", "Frontend Dev");
Employee dev2 = new Developer("Bob", "Backend Dev");
Employee designer = new Designer("Clara");

Manager manager = new Manager("Daniel");
manager.addEmployee(dev1);
manager.addEmployee(dev2);
manager.addEmployee(designer);

manager.showDetails();

🌐 Real-World Analogy

Think of a corporate org chart. Employees report to managers, who report to directors, and so on. Whether it’s a single employee or a whole department, you can interact with them the same way.

⚠️ Pitfalls to Avoid

  • ❌ Making composite and leaf objects overly different in behavior
  • ❌ Violating the Liskov Substitution Principle by adding methods only useful for composites
  • ❌ Over-complicating when a simple flat structure would do

βœ… Best Practices

  • Ensure your interface supports the common operations for both leaves and composites
  • Keep the hierarchy clean and recursive-friendly
  • Design for extensibility: your components should be able to grow easily

πŸ“˜ Recap

  • Composite Pattern allows you to treat individual and grouped objects uniformly
  • Great for recursive structures like trees, menus, file systems, and organizations
  • Promotes flexibility and scalability in system design
  • Real-world analogy: departments made up of employees and sub-departments