Lesson 3
Composite Pattern
Composite Pattern

In this unit, we will delve into the Composite pattern, a pivotal structural design pattern that facilitates treating individual objects and compositions of objects in a unified manner. This pattern is particularly useful when you need to represent part-whole hierarchies, and you want to be able to interact with those hierarchies in a consistent manner.

What You'll Learn

In this lesson, you will master:

  • The core concept of the Composite pattern.
  • How to implement the Composite pattern using a real-world example involving employees in a company.
  • The significance and benefits of using the Composite pattern in software development.

Let's explore the Composite pattern through a practical example.

Implementing the Composite Pattern

Our example will focus on an organizational structure where we have different types of employees, such as Developers and Managers, and we want to group them within a company directory. This example will help you understand how to manage a collection of objects in a tree structure.

Step 1: Define the Component Interface

First, we define the Employee interface, which declares a method for showing employee details.

Java
1public interface Employee { 2 void showEmployeeDetails(); 3}

In this example, Employee is the component interface that declares the showEmployeeDetails method. All concrete employee classes will implement this interface.

Step 2: Implement the Leaf Components

Next, we create the Developer and Manager classes that implement the Employee interface. These classes represent the leaf nodes in the composite structure.

Developer class:

Java
1public class Developer implements Employee { 2 private String name; 3 private long empId; 4 private String position; 5 6 public Developer(long empId, String name, String position) { 7 this.empId = empId; 8 this.name = name; 9 this.position = position; 10 } 11 12 @Override 13 public void showEmployeeDetails() { 14 System.out.println(empId + " " + name + " " + position); 15 } 16}

Manager class:

Java
1public class Manager implements Employee { 2 private String name; 3 private long empId; 4 private String position; 5 6 public Manager(long empId, String name, String position) { 7 this.empId = empId; 8 this.name = name; 9 this.position = position; 10 } 11 12 @Override 13 public void showEmployeeDetails() { 14 System.out.println(empId + " " + name + " " + position); 15 } 16}

The Developer and Manager classes provide the specific details for developers and managers by implementing the showEmployeeDetails method.

Step 3: Create the Composite

The CompanyDirectory class will implement the Employee interface and represent the composite structure that contains a list of employees.

Java
1import java.util.ArrayList; 2import java.util.List; 3 4public class CompanyDirectory implements Employee { 5 private String directoryName; 6 private List<Employee> employeeList; 7 8 public CompanyDirectory(String directoryName) { 9 this.directoryName = directoryName; 10 this.employeeList = new ArrayList<>(); 11 } 12 13 @Override 14 public void showEmployeeDetails() { 15 System.out.println("Company Directory: " + directoryName); 16 for (Employee emp : employeeList) { 17 emp.showEmployeeDetails(); 18 } 19 } 20 21 public void addEmployee(Employee emp) { 22 employeeList.add(emp); 23 } 24 25 public void removeEmployee(Employee emp) { 26 employeeList.remove(emp); 27 } 28}

The CompanyDirectory class acts as a composite by maintaining a list of Employee objects and implementing the showEmployeeDetails method to display the details of all employees in the directory.

Step 4: Using the Composite

Here's how you can use the CompanyDirectory composite along with Developer and Manager leaf nodes.

Java
1public class Main { 2 public static void main(String[] args) { 3 Developer dev1 = new Developer(100, "John Doe", "Pro Developer"); 4 Developer dev2 = new Developer(101, "Jane Smith", "Entry Developer"); 5 Manager man1 = new Manager(200, "Bob Brown", "Senior Manager"); 6 7 CompanyDirectory directory = new CompanyDirectory("Engineering Department"); 8 directory.addEmployee(dev1); 9 directory.addEmployee(dev2); 10 directory.addEmployee(man1); 11 12 directory.showEmployeeDetails(); 13 } 14}

In the Main class, we create instances of Developer and Manager and add them to the CompanyDirectory. When we call the showEmployeeDetails method on CompanyDirectory, it displays the details of all employees in the directory.

Why It Matters

The Composite pattern is significant in software development for various reasons:

  • Uniformity: It allows you to treat both individual objects and composites uniformly. This simplifies the way you interact with part-whole hierarchies.
  • Flexibility: It makes it easy to add new types of components, such as new types of employees, without changing the existing code.
  • Maintainability: It organizes hierarchies in a structured manner, making the code easier to maintain and extend.

By mastering the Composite pattern, you can design more flexible and maintainable systems that can handle complex hierarchical structures with ease. This lesson prepares you to create and manage composite objects effectively, enhancing your ability to build scalable and organized software.

Ready to solidify your understanding with some hands-on practice? Let's dive into the practice section!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.