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 interact with those hierarchies in a consistent manner.
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.
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.
First, we define the Employee
interface, which declares a method for showing employee details.
Kotlin1interface Employee { 2 fun showEmployeeDetails() 3}
In this example, Employee
is the component interface that declares the showEmployeeDetails
method. All concrete employee classes will implement this interface.
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:
Kotlin1data class Developer(val empId: Long, val name: String, val position: String) : Employee { 2 override fun showEmployeeDetails() { 3 println("$empId $name $position") 4 } 5}
Manager
class:
Kotlin1data class Manager(val empId: Long, val name: String, val position: String) : Employee { 2 override fun showEmployeeDetails() { 3 println("$empId $name $position") 4 } 5}
The Developer
and Manager
classes provide the specific details for developers and managers by implementing the showEmployeeDetails
method.
The CompanyDirectory
class will implement the Employee
interface and represent the composite structure that contains a list of employees.
Kotlin1class CompanyDirectory(val directoryName: String) : Employee { 2 private val employeeList: MutableList<Employee> = mutableListOf() 3 4 override fun showEmployeeDetails() { 5 println("Company Directory: $directoryName") 6 for (emp in employeeList) { 7 emp.showEmployeeDetails() 8 } 9 } 10 11 fun addEmployee(emp: Employee) { 12 employeeList.add(emp) 13 } 14 15 fun removeEmployee(emp: Employee) { 16 employeeList.remove(emp) 17 } 18}
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.
Here's how you can use the CompanyDirectory
composite along with Developer
and Manager
leaf nodes.
Kotlin1fun main() { 2 val dev1 = Developer(100, "John Doe", "Pro Developer") 3 val dev2 = Developer(101, "Jane Smith", "Entry Developer") 4 val man1 = Manager(200, "Bob Brown", "Senior Manager") 5 6 val directory = CompanyDirectory("Engineering Department") 7 directory.addEmployee(dev1) 8 directory.addEmployee(dev2) 9 directory.addEmployee(man1) 10 11 directory.showEmployeeDetails() 12}
When running the main
function, the expected output is:
1Company Directory: Engineering Department 2100 John Doe Pro Developer 3101 Jane Smith Entry Developer 4200 Bob Brown Senior Manager
In this example, 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.
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.