Design Pattern | Composite Pattern
What Is the Composite Pattern?
- The word composite means mixed or compound.
- The Composite pattern creates a recursive structure by treating containers and contents uniformly.
- To treat directories and files together as directory entries, it can be useful to treat containers and contents as the same kind of thing. For example, a container may contain contents, and it may also contain another container. In this way, a recursive structure can be created.
- In GoF design patterns, it is classified as a structural design pattern.
Composite Pattern Example Program
This example program displays a list of directories and files.
Class Diagram

1. Entry Class
This is the base class for File and Directory.
Entry.java
package com.devkuma.designpattern.structural.composite;
public abstract class Entry {
public abstract String getName();
protected abstract void printList(String prefix);
public void printList() {
printList("");
}
}
2. File Class
This class represents a file.
File.java
package com.devkuma.designpattern.structural.composite;
public class File extends Entry {
private String name;
public File(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
protected void printList(String prefix) {
System.out.println(prefix + "/" + name);
}
}
3. Directory Class
This class represents a directory.
Directory.java
package com.devkuma.designpattern.structural.composite;
import java.util.ArrayList;
import java.util.Iterator;
public class Directory extends Entry {
private String name;
private ArrayList<Entry> directory = new ArrayList();
public Directory(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
public Entry add(Entry entry) {
directory.add(entry);
return this;
}
@Override
protected void printList(String prefix) {
System.out.println(prefix + "/" + name);
Iterator<Entry> it = directory.iterator();
while (it.hasNext()) {
Entry entry = it.next();
entry.printList(prefix + "/" + name);
}
}
}
4. Main Class
This is the class that executes the main processing.
Main.java
package com.devkuma.designpattern.structural.composite;
public class Main {
public static void main(String[] args) {
Directory workspaceDir = new Directory("workspace");
Directory compositeDir = new Directory("composite");
Directory testDir1 = new Directory("test1");
Directory testDir2 = new Directory("test2");
workspaceDir.add(compositeDir);
workspaceDir.add(testDir1);
workspaceDir.add(testDir2);
File directory = new File("Directory.java");
File entity = new File("Entity.java");
File file = new File("file.java");
File main = new File("main.java");
compositeDir.add(directory);
compositeDir.add(entity);
compositeDir.add(file);
compositeDir.add(main);
workspaceDir.printList();
}
}
5. Execution Result
/workspace
/workspace/composite
/workspace/composite/Directory.java
/workspace/composite/Entity.java
/workspace/composite/file.java
/workspace/composite/main.java
/workspace/test1
/workspace/test2
Advantages
Because all objects(File and Directory) share a common abstract class, the client does not need to be aware of whether something is a File or a Directory and can treat them uniformly.
Also, even if a new class such as SymbolicLink is added, client processing is not affected as long as the interface of the base class(Entry) does not change.