Composite design Pattern in Java – with examples

Every programmer comes across a scenario, when data needs to be represented as a tree structure.

While dealing with tree structure many times we need to treat different objects in similar ways, like file and directory. File and directory both having size, name, creation time etc. Another example can be of employee hierarchy in an organization. Manager, CEO and employees all are instances of a Person.

Composite design pattern can come very handy in these situations.

What is Composite design pattern?

Composite design pattern in java is one of the  structural design patterns.

From the name, "Composite" means the combination or made from different parts. So this pattern provides solution to operate group of objects and single object in similar way.

The two most important uses of the composite design pattern are,

  1. Objects can be represented in a tree structure hierarchy
  2. Composite and individual objects are treated uniformly

There are many real life examples for composite design pattern.

composite design pattern directory structure

The most common example can be file-directory structure. As shown in image.

Node can be a directory or a file.

Even though they are different type of objects, many times we need to treat them similarly . For eg: we can check size of file as well as size of directory. The size of directory is sum of size of all the files in that directory.

Image displaying organisation hierarchy

Another example can be the employee hierarchy in an organization.

In the image lets say we have CEO as top node, then mangers and then employees.

CEO manages the mangers. And has group of employees.

All employees, managers and the CEO are instances of a person.

Composite design pattern structure

composite design pattern structure

The image shows the basic structure of the composite design pattern.

There are 2 types of objects Composite object and Leaf object.

1) Composite Object : It is an object which contains other object. This has children e.g: Directory(file folder)
2) Leaf Object : It is a single object. It does not have children e.g: File

Where can we use composite pattern?

There are so many cases where we can use composite design pattern in any programing language. Some of them can be:

  • The data needs to be represented in hierarchy or tree structure
  • When we need parent-Child relationship
  • When parent and child objects need to be treated in same way

Steps to implement composite design Pattern?

  • We need to define leaf and composite objects as same data type
    • By implementing interface or extending class
  • Then write(implement) common method in all the leaf and composite objects
  • In Leaf node perform their own desired behavior
  • In Composite object write customized function or each child of this node can call this function

UML diagram for composite design pattern implementation

Composite design pattern java Class Diagram

As shown in the image we will create interface for "File". Then we will have two different classes. One for Directory type and second for other than directory like .txt, .doc, etc
The Directory class is composite class that can contain other files or directories.

Implementing Composite Design Pattern in Java

Let's implement the example for file directory structure. We will create child1.txt and child2.txt files . Then we will have root directories. Root directories will contain child1.txt and child2.txt files.

Then we will try to get size of child1.txt and root directory.

As explained in step 1 lets create parent type as File interface

interface File {
    public String getType();
    public Long getSize();
}

Now lets create classes for file and directory type

class TextFile implements File {

private Long size;


public TextFile(Long size) {

this.size = size;

}


public String getType() {

return "txt";

}

public Long getSize() {

return this.size;

}


}
class Directory implements File {

private List <File> files = new ArrayList<>();

public String getType() {

return "directory";

}

public void addFile(File file) {

files.add(file);

}

public Long getSize() {

Long size = 0L;

for (File file : files) {

size = size + file.getSize();

}

return size;

}

}

Now we have implemented two leaf and one composite object. Both objects are of same time 'File'.

We can use getSize() on TextFile class or Direcotry class.

Now let's test the code using main method.

class Application {

	public static void main(String[] args) {
		TextFile child1 = new TextFile(100L);
		TextFile child2 = new TextFile(200L);

		Directory root= new Directory(100L);
		root.addFile(child1);
		root.addFile(child2);

		System.out.println(child1.getSize());      // output : 100
		System.out.println(root.getSize());    // output : 300
	}
}

Benefits 

  • Data can be represented as tree structure
  • Same operations can be performed on different type of objects
  • Reduces the overhead of handling different type of objects
  • Client process doesn't need to worry about node data type because all objects are represented by same parent type

Limitations

  • Objects should be compatible
  • If the objects behavior is different we can not use it
  • Complexity can be increased

Fast track reading 

  • Composite design pattern is one of the  structural design patterns
  • Composite and individual object is treated uniformly
  • There are 2 types of objects Composite object and Leaf object.
  • Composite Object : it is a object which contains other object
  • Leaf Object : it is a single object
  • Data can be represented as tree structure

Related topics you might want to check out

Leave a Reply

Your email address will not be published. Required fields are marked *