How to use Composite Design Pattern in Java?
Hello Java programmers, if you want to learn about Composite Design Pattern in Java , such as how to implement Composite Design Pattern and when to use it, then you have come to the right place. In this article, we will discuss Composite Design Pattern . Composite Design Pattern is a behavioral design pattern from GOF, first described in their classic book Design Patterns. Composite pattern allows us to build a structure as a tree, which contains leaves and composites.
A leaf is an object that corresponds to a leaf node in the tree and contains no other objects, whereas a composite object contains other composites or leaves. One of the most powerful features of this design pattern is that we can treat leaves and composites in the same way.
For example, we have an organizational chart that contains every employee in hierarchical order. Some employees are managers and they contain references to other employees who report to them. If we need to print all the contents of the employee list directly, we have to check if the specific employee is a manager to do this.
One way to remove this check is to use the Composite pattern which allows treating both normal employees and managers in the same way and that is what we will see in this article. We will use this example to implement the Composite design pattern in Java .
What is the Composite Design Pattern? An Example
Following is an example of Composite pattern in Java. Here, we are using Composite pattern to represent employees in an organization. Here some of the employees are managers and they are composite objects because they contain references to other employees who report to them.
If we need to print instructions for a list of employees (employees reporting to him), we cannot do this without checking if the employee is a manager. One way to remove this check is to use the composite pattern, which allows to treat regular employees and managers in the same way.
In composite design pattern, we have an Component
object which defines a method for leaf objects and composite objects, in this case Employee, which has methods like add(Employee e)
, remove(Employee e)
and along with regular methods like getId()
, getName()
.
In our example, Employee is an abstract class that provides default implementations for most of the methods and it has two concrete subclasses Developer and Manager .
The Manager overrides directs()
the method to return a list of Employees that report to him, while the developer simply returns an empty list, which is also NullPointerException
a good example of using the Null Object pattern to avoid .
Here is the complete code for this example
Employee.java
import java.util.List; public abstract class Employee { protected int id; protected String name; public Employee(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public String getName() { return name; } public void add(Employee e) { throw new UnsupportedOperationException(); } public void remove(Employee e) { throw new UnsupportedOperationException(); } public Employee getChild(int i) { throw new UnsupportedOperationException(); } public List<Employee> directs() { throw new UnsupportedOperationException(); } @Override public String toString() { return String.format("%s: %d", name, id); } }
Developer.java (Leaf object)
import java.util.Collections; import java.util.List; public class Developer extends Employee { public Developer(int id, String name) { super(id, name); } @Override public List<Employee> directs() { return Collections.EMPTY_LIST; } }
Manager.java
import java.util.ArrayList; import java.util.List; public class Manager extends Employee { private List<Employee> directs = new ArrayList<>(); public Manager(int id, String name) { super(id, name); } @Override public void add(Employee e) { directs.add(e); } @Override public void remove(Employee e) { directs.add(e); } @Override public Employee getChild(int i) { return directs.get(i); } @Override public List<Employee> directs() { return directs; } }
CompositePattern.java
import java.util.ArrayList; import java.util.List; public class CompositePatternTest { public static void main(String args[]) { Developer john = new Developer(101, "John"); Developer robin = new Developer(102, "Robin"); Developer peter = new Developer(103, "Peter"); Developer luke = new Developer(104, "Luke"); Developer amy = new Developer(105, "Amy"); Manager steve = new Manager(106, "Steve"); steve.add(john); steve.add(robin); steve.add(peter); Manager frank = new Manager(107, "Frank"); frank.add(luke); frank.add(amy); frank.add(steve); List<Employee> org = new ArrayList<>(); org.add(john); org.add(robin); org.add(peter); org.add(luke); org.add(amy); org.add(steve); org.add(frank); for (Employee e : org) { System.out.printf("%s manages %s %n", e.getName(), e.directs()); } } }
As you can see, directs()
there is no conditional check in the code that operates on the list of employees before calling the method. We can also use this pattern to print an organizational chart, where each manager is responsible for printing his reporters, and receive()
the message is communicated to each employee by defining the method, and each manager will further communicate the message to his subordinates.
When to use Composite design pattern in Java?
If we have a hierarchical or tree-like structure, such as employees in an organization, family members in a household, nodes in an XML document, etc., we should consider using the composite pattern.
Another key thing to remember
to find usage of the Composite design patterninstanceof
is the use of the operator. If we are receiving an object, instead of calling a method on it directly, checking for a specific type, then Composite is a way to handle them uniformly.
In this example, if we need to call directs()
a method on Employee, we can also instanceof Manager
do so by checking each employee's code. The Composite pattern allows us to handle both leaf objects and composite objects in a unified way.
This is a useful pattern that can simplify our code in many cases.
Here is a nice UML diagram of the Composite design pattern which will help you understand this pattern better.
That's all about what is Composite design pattern in Java. We have not only learned how to implement Composite design pattern in Java but also learned when to use Composite pattern and what are the advantages and disadvantages of Composite pattern. It is one of the usage pattern in the design pattern library for Java developers.
As we can see, one of the main advantages of this pattern is that the code is simple and easy to read, which is possible because composite objects and node objects are treated in a similar way.
This same characteristic is also its biggest disadvantage, as it allows clients to call composite methods on node objects that should not be called or have no valid behavior. As with any design decision, the trade-offs must be weighed if the advantages of the composite pattern outweigh the risks of erroneous method calls.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Article URL:https://www.jiyik.com/en/xwzj/algorithm_9854.html
Related Articles
Java Decorator Design Pattern Example
Publish Date:2025/03/19 Views:115 Category:ALGORITHM
-
Hello everyone, if you want to learn about Decorator Design Pattern in Java , then you have come to the right place. As design patterns are very important while building software and equally important in any core Java interview, it is alway
How to find the IP address of the local host in Java
Publish Date:2025/03/17 Views:98 Category:NETWORK
-
The Java Networking API provides a way to find the local host IP address from a Java program using the java.net InetAddress class. It is rare that you need the local host IP address in a Java program. Most of the time, I use the Unix command to find t
Why do you need to bind event handlers in React Class Components?
Publish Date:2025/03/16 Views:58 Category:React
-
When using React, we must have come across control components and event handlers. We need to use `.bind()` in the constructor of the custom component to bind these methods to the component instance. As shown in the following code:
Do you understand JavaScript closures?
Publish Date:2025/02/21 Views:111 Category:JavaScript
-
The function of a closure can be inferred from its name, suggesting that it is related to the concept of scope. A closure itself is a core concept in JavaScript, and being a core concept, it is naturally also a difficult one.
Do you know about the hidden traps in variables in JavaScript?
Publish Date:2025/02/21 Views:183 Category:JavaScript
-
Whether you're just starting to learn JavaScript or have been using it for a long time, I believe you'll encounter some traps related to JavaScript variable scope. The goal is to identify these traps before you fall into them, in order to av
How much do you know about the Prototype Chain?
Publish Date:2025/02/21 Views:156 Category:JavaScript
-
The prototype chain can be considered one of the core features of JavaScript, and certainly one of its more challenging aspects. If you've learned other object-oriented programming languages, you may find it somewhat confusing when you start
如何在 JavaScript 中合并两个数组而不出现重复的情况
Publish Date:2024/03/23 Views:89 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中合并两个数组,以及如何删除任何重复的数组。
如何检查 JavaScript 中的变量是否为字符串
Publish Date:2024/03/23 Views:159 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中检查变量是否为字符串。
在 JavaScript 中扁平化一个数组
Publish Date:2024/03/23 Views:115 Category:JavaScript
-
本教程介绍了如何在 JavaScript 中扁平化一个数组。