The Composite pattern is a structural design pattern describes a group of objects that is treated the same way as a single instance of the same type of object. A Composite intends to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

The Composite pattern allows the creation of objects with properties that are primitive items or a collection of objects. Each item in the collection can hold other collections themselves, creating deeply nested structures. We can treat the whole collection of objects the same way we would treat any of the individual objects in the collection.

It organizes the objects into a tree structure, and since each composite object contains a method to get its children, we can hide the implementation and organize the children in any preferred way.

Using's Benefits

By using the Composite design pattern, we would be able to call a function on a top-level object and have the results happen to any or all of the nodes in the composite structure. Another benefit is that the objects in the composite are loosely coupled because they all just follow the same interface. It also gives an excellent structure to the objects, rather than keeping them all in separate variables or an array.


There is a hierarchy to this pattern where we have types of objects: leaf and composite. The composite objects and The leaves do not have any children, while the composite does. However, it is recursive nature that represents the primary factor in this pattern.

Composite Structure


Some examples from real life that reflect the Composite pattern nature is the directories in most of the operating system. Directories contain files, each of which could be a directory. Another example is menus. They include menu items, each of which could be a menu in itself.

Let's take the directory structure and have it as an example that we would write a code for.

function File(name) { = name;

File.prototype.display = function () {

function Directory(name) { = name;
    this.files = [];

Directory.prototype.add = function (file) {

Directory.prototype.remove = function (file) {
    for (let i = 0, length = this.files.length; i < length; i++) {
        if (this.files[i] === file) {
            this.files.splice(i, 1);
            return true;
    return false;

Directory.prototype.getFileName = function (index) {
    return this.files[index].name;

Directory.prototype.display = function() {
    for (let i = 0, length = this.files.length; i < length; i++) {
        console.log("   ", this.getFileName(i));

directoryOne = new Directory('Directory One');
directoryTwo = new Directory('Directory Two');
directoryThree = new Directory('Directory Three');

fileOne = new File('File One');
fileTwo = new File('File Two');
fileThree = new File('File Three');





Directory One
    File One
    File Two
Directory Two
    File One
Directory Three
    File One
    File Two
    File Three