Disclosure: This article may contain affiliate links. When you purchase, we may earn a commission.

Composite Design Pattern Example in Java and Object Oriented Programming

Hello guys, if you are wondering how to use Composite design pattern in Java then you are at the right place. Composite design pattern is another object oriented design pattern introduced by Gang of Four in there timeless classic book Design pattern : Elements of Reusable software. Composite pattern as name suggest is used to compose similar things together, like similar objects. It implements an interface and also contains other objects which implements the same interface, also known as containee. One of the best example of Composite pattern from Java standard library is Swing's container classes e.g. Panel, which not only are Components by themselves, but also contains other components like JButton, Label, JTable etc. 


When we perform any operation on Composite object, it delegates it to individual object, from which it is composed of. For example, when we request paint() on panel, it ends up requesting paint() on each component to let them draw themselves. 

Another advantage of Composite pattern is that, it allows client to transparently deal with composite and individual object. Client doesn't need to perform any specific logic, while calling methods on composite or individuals, because composite also implements same interface, as there components. 

It's one of the core design pattern along with Strategy, Decorator and Factory pattern. In this article, we will seen an example of Composite design pattern to illustrate the idea of composing and taking advantage of existing objects.





Composite Design Pattern Example in Java

In last article, we have seen example of Strategy pattern, to implement different filtering strategies for messages. In this example, we will extend requirement from there. Suppose, now we need to filter message if it's type is either XML or it's content contains a specific word. We can do this by using Composite design pattern, a powerful pattern from a Gang of Four.

Here is the UML diagram of Composite design pattern to understand the structure of this pattern:

Composite Design Pattern Example in Java

You can see that we have a container object which implement the same interface called "Element" which is also implemented by Containee object which it contains but for functionality it delegate calls to actual element.

Let's create a composite strategy, which contains our existing Strategy classes e.g. FilterByType and FilterByKeyWord and also implements FilteringStrategy interface (for full code, see earlier example). 

Since our composite Strategy is just another implementation, we can pass this to our filter() method, and it's isFilterable() method will return true, if either of contained Strategy return true. By applying this technique, we can implement a wide range of composite objects e.g. AND strategy or XOR strategy. 



Here is the code for our Composite class :

public class ORStrategy implements FilteringStrategy{
    List strategies = new ArrayList();
   
    public void addStrategy(FilteringStrategy strategy){
        strategies.add(strategy);
    }
   
    public void removeStrategy(FilteringStrategy strategy){
        strategies.remove(strategy);
    }
   
    @Override
    public boolean isFilterable(Message msg) {
        for(FilteringStrategy strategy : strategies){
            if(strategy.isFilterable(msg)){
                return true;
            }
        }
        return false;       
    }
   
     @Override
    public String toString() {
        return "ORStrategy";
    }
}

You can see that apart from isFilterable() method, which comes from interface, it also contains method for adding and removing strategies. While removing strategy by remove(Object) method, make sure your class implements equals() and hashCode() method properly. Here is the test class, which makes use of this composite pattern implementation :

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Java program to demonstrate how to use 
 * Composite design pattern in Java.
 * Composite pattern allows to take advantage of existing object
 * with added behavior.
 *
 * @author Javin Paul
 */
public class CompositePattern {

    private static final Logger logger 
             = LoggerFactory.getLogger(CompositePattern.class);

    public static void main(String args[]) {
        List messages = new ArrayList();
        messages.add(new Message(MessageType.TEXT, 100, 
              "This is first message"));
        messages.add(new Message(MessageType.XML, 200, 
                 "How are you "));
        messages.add(new Message(MessageType.TEXT, 300, 
                "Second Message"));
        messages.add(new Message(MessageType.TEXT, 400,
         "Wrong Message, should be filtered"));
       
       
        // instantiating composite strategy -
        // a composite pattern implementation
        ORStrategy composite = new ORStrategy();
 
        FilteringStrategy byType = new FilterByType(MessageType.XML);
        FilteringStrategy byWord = new FilterByKeyword("Wrong");
       
        // adding strategies into composite
        composite.addStrategy(byType);
        composite.addStrategy(byWord);
       
        // Now filtering message
        messages = filter(messages, composite );
      
       
    }

    /*
     * This method confirms Open Closed design principle,
     * It's open for modification, because
     * you can provide any filtering criterion by proving
     * implementation of FilteringStrategy, but
     * no need to change any code here. New functionality
     * will be provided by new code.
     */
    public static final List filter(List messageList, 
                    FilteringStrategy strategy){
       
        Iterator itr = messageList.iterator();
       
        while(itr.hasNext()){
            Message msg = itr.next();           
            if(strategy.isFilterable(msg)){
                logger.info(strategy.toString() + msg);
                itr.remove();
            }
        }
       
        return messageList;
    }
   
}

Output:
- ORStrategy Message{type=XML, size=200, 
content=<data>How are you </data>}
- ORStrategy Message{type=TEXT, size=400, 
content=Wrong Message, should be filtered}



That's all in this example of Composite pattern in Java. Key thing to remember about this pattern is that it implements same interface, as the object it contains. Composite Object can be used in place of Component object as well, because they implement same interface. Once again, I strongly recommend to read Head First design pattern and Gang of four pattern books to learn more Composite design pattern and it's different use cases.


Other Java Design Pattern Tutorials and Examples you may like
  • 5 Free Courses to learn Object Oriented Programming (courses)
  • How to implement Command design pattern in Java? (Command pattern)
  • Difference between Factory and Dependency Injection Pattern? (answer)
  • 7 Best Courses to learn Design Pattern in Java (courses)
  • 7 Best Books to learn the Design Pattern in Java? (books)
  • How to create thread-safe Singleton in Java (example)
  • How to implement the Strategy Design Pattern in Java? (example)
  • 18 Java Design Pattern Interview Questions with Answers (list)
  • Difference between Factory and AbstractFactory Pattern? (example)
  • How to design a Vending Machine in Java? (questions)
  • Difference between State and Strategy Design Pattern in Java? (answer)
  • 20 System Design Interview Questions (list)
  • Top 5 Courses to learn Design Patterns in Java (courses)
  • How to use Adapter design pattern in Java (Adapter pattern)
  • 5 Free Courses to learn Data Structure and Algorithms (courses)

Thanks for reading this Composite design pattern tutorial. Just remember that both Composite and Individual object it contains implement the same interface and the best example is the paint() method which is used to paint the canvas which is composted by many components. When you call the pain() method on Canvas or Panel then call paint() method of individual elements and whole canvas is painted by individual elements. 

No comments:

Post a Comment

Feel free to comment, ask questions if you have any doubt.