Composite Design Pattern Using Java

Introduction

A composite design pattern is a structural design pattern. It allows developers to create multiple nested objects of the same type to complete one single system hierarchy.

Players in this pattern

  • Component: this player defines a base contract with the composite class to allow to create nested objects.
  • Composite: this player, is one who will implement the contract defined by the component.
  • Client: this player, with the help of a composite player, will complete the system hierarchy for a particular requirement

We will see with an example.

Requirement

Build a smart city with smart block features.

We will define 3 players.

  • AbstractBlock: Component
  • Block: Composite
  • Client

We will build an Abstract block with Add and remove block features. If we want we can implement Add, and Remove features explicitly. In my case, I am using List, by default I will be having Add and Remove features available for adding/removing blocks.

import java.util.List;
public abstract class AbstractBlock {
    public String name;
    public double size;
    public abstract void buildBlock();
    public List<AbstractBlock> subBlocks;
}

Now implement a Composite object i.e. Block by implementing/inheriting a component (i.e. in our code AbstractBlock).

import java.util.*;
public class Block extends AbstractBlock {
    public Block() {
        subBlocks = new ArrayList<>();
    }
    @Override
    public void buildBlock() {
        System.out.println("Block built with name " + name + " with size " + size + " unit");
    }
}

 In the above code we can see that, we provided the implementation for the buildBlock method. Based on our need we can make concrete or non-concrete methods as well.

Below is the client class code.

public class Client {

    public static void main(String[] args) {
        AbstractBlock smartCity = new Block();
        smartCity.name = "SmartCity";
        smartCity.size = 100000;
        AbstractBlock smartlayOut = new Block();
        smartlayOut.name = "SmartlayOut";
        smartlayOut.size = 10000;
        smartCity.subBlocks.add(smartlayOut);
        AbstractBlock smartHome = new Block();
        smartHome.name = "smartHome";
        smartHome.size = 1000;
        smartlayOut.subBlocks.add(smartHome);
        AbstractBlock smartRoom = new Block();
        smartRoom.name = "smartRoom";
        smartRoom.size = 1000;
        smartHome.subBlocks.add(smartRoom);
        AbstractBlock smartLocker = new Block();
        smartLocker.name = "smartLocker";
        smartLocker.size = 20;
        smartRoom.subBlocks.add(smartLocker);
        AbstractBlock smartFolder = new Block();
        smartFolder.name = "smartFolder";
        smartFolder.size = 10;
        smartLocker.subBlocks.add(smartFolder);
        AbstractBlock smartFile = new Block();
        smartFile.name = "smartFile";
        smartFile.size = 5;
        smartFolder.subBlocks.add(smartFile);
        Build(smartCity);
        System.out.println();
    }
    private static void Build(AbstractBlock block) {
        block.buildBlock();
        block.subBlocks.forEach(a -> Build(a));
    }
}

In the above code, we can see that the client has a unitized composite object and is built first.

  • Smart City followed by Smart Layout
  • Smart Layout followed by Smart Home
  • Smart Home followed by Smart Room
  • Smart Room followed by Smart Locker
  • Smart Locker followed by Smart Folder
  • Smart Folder followed by Smart File

After executing this code we can same hierarchy in tree format. For easy understating, I put snap ob object hierarchy in tree format.

Hierarchy

Below is the output snap.

Below

When we have a requirement to implement some nested objects with the same type, then we can go for this design pattern.

We can extend this composite object to any extent with N numbers of blocks inside blocks.

Summary

Above is a simple example of using a composite design pattern, you can download the uploaded source code and try adding more blocks. I hope it helps.


Similar Articles