DEV Community

eidher
eidher

Posted on • Updated on

Composite Pattern

Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

Alt Text

Participants

  • Component: declares the interface for objects in the composition. Implements default behavior for the interface common to all classes, as appropriate. Declares an interface for accessing and managing its child components. (optional) defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate.
  • Leaf: represents leaf objects in the composition. A leaf has no children. Defines behavior for primitive objects in the composition.
  • Composite: defines behavior for components having children. Stores child components. Implements child-related operations in the Component interface.
  • Client: manipulates objects in the composition through the Component interface.

Code

public class Main {

    public static void main(String[] args) {
        // Create a tree structure
        Composite root = new Composite("root");
        root.add(new Leaf("Leaf A"));
        root.add(new Leaf("Leaf B"));

        Composite comp = new Composite("Composite X");
        comp.add(new Leaf("Leaf XA"));
        comp.add(new Leaf("Leaf XB"));

        root.add(comp);
        root.add(new Leaf("Leaf C"));

        // Add and remove a leaf
        Leaf leaf = new Leaf("Leaf D");
        root.add(leaf);
        root.remove(leaf);

        // Recursively display tree
        root.display(1);
    }
}

public abstract class Component {
    protected String name;

    public Component(String name) {
        this.name = name;
    }

    public abstract void add(Component c);

    public abstract void remove(Component c);

    public abstract void display(int depth);
}

public class Composite extends Component {
    private List<Component> children = new ArrayList<>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        children.add(component);
    }

    @Override
    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);

        for (Component component : children) {
            component.display(depth + 2);
        }
    }
}

public class Leaf extends Component {

    public Leaf(String name) {
        super(name);
    }

    @Override
    public void add(Component c) {
        System.out.println("Cannot add to a leaf");
    }

    @Override
    public void remove(Component c) {
        System.out.println("Cannot remove from a leaf");
    }

    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);
    }
}
Enter fullscreen mode Exit fullscreen mode

Output

-root
---Leaf A
---Leaf B
---Composite X
-----Leaf XA
-----Leaf XB
---Leaf C
Enter fullscreen mode Exit fullscreen mode

Top comments (0)