Design Pattern: Composite Pattern

Summary

Pattern NameComposite Pattern
Pattern TypeStructural Pattern
ScopeObject
TaglineHandle list of objects (compositions) of the same interface together
Use casesWhen objects of the same type need to be handled together
and the handling class needs to implement the same interface
Related PatternsDecorator
Iterator
Flyweight
Visitor
Difficulty LevelEasy
Implementations

Definition

When there is a bunch of classes that are of the same type (implement the same interface), and we need to use them as composition (not as individual objects), we can use Composite pattern.

Composite pattern helps to use the classes in a composition, so that the client can use the composition and individual classes can be treated in the same way.

We can think of the composition as depicted in the diagram below. Each composition consists of one or more individual objects or compositions.

Use Cases

Here are the use cases of Composite pattern:

  • When we want the client to treat individual objects and compositions(groups) of objects the same way.
  • When we need to handle a list of items(or component tree), and maintain the order/sequence of the items.
  • Where there are concerns about memory usage or performance while handling a list of objects (of the same type).

Implementation

Composite pattern implementation has 3 parts.

  1. Component: this is the interface that all classes implement so that the composition of classes can work.
  2. Leaf: these are the individual classes.
  3. Composite: this class implements the same interface as the leaf, and handles the composition/leaf/group of individual classes.

Use the following steps and criteria to implement Composite pattern.

  1. Create an interface, that the leaf classes and composite class will implement.
  2. Implement the interface for all the Leaf classes. Leaf classes do not have any reference to other classes.
  3. Create a composite class.
  4. Maintain a list of Leaf objects in the composite class.
  5. Implement methods to add and remove Leaf objects in the composite class.
  6. Implement the base interface for composite class.
  7. In the composite class, the implemented methods will call the methods of all Leaf objects in the list (in loops).
  8. In the client add/remove the Leaf object in the list of composite classes, then call the functions of the composite class when required.

Examples

Example #1: Transport Composite List

Let’s consider a transport system in an application. Take a look at the class diagram first:

Here we have different transport available – car, bike, plane. We will use the composite pattern (using TransportGroup class) to handle a list/group of transports.

Transport Interface

Interface for all transports, both individual and group.

// Transport interface

interface Transport

    function start()

    function operate()

    function stop()

end interface

Transport Individual Classes

Individual transport classes. All these classes implement the Transport interface.

// Bike class

class Bike implements Transport
    
    function start()
        print "Starting Bike..."
    end function

    function operate()
        print "Riding Bike"
    end function

    function stop()
        print "Stopping Bike..."
    end function

end class


// Plane class

class Plane implements Transport
    
    function start()
        print "Starting Plane..."
    end function

    function operate()
        print "Flying Plane"
    end function

    function stop()
        print "Stopping Plane..."
    end function

end class


// Car class

class Car implements Transport

    function start()
        print "Starting Car..."
    end function

    function operate()
        print "Driving Car"
    end function

    function stop()
        print "Stopping Car..."
    end function

end class

Composite Class

A composite class for groups of transport. This implements the Transport interface and holds an array of transport objects to maintain a list.

For implementing the Transport in all the function definitions, this composite class performs the operations on the list.

class TransportGroup implements Transport

    var transportList: Transport[]    // Maintain a list of Transport Leaf classes

    // Override start of Transport interface
    function start()
        loop transportList as transport
            transport.start()
        end loop
    end function

    // Override operate of Transport interface
    function operate()
        loop transportList as transport
            transport.operate()
        end loop
    end function

    // Override stop of Transport interface
    function stop()
        loop transportList as transport
            transport.stop()
        end loop
    end function

    function addTransport(Transport transport)
        // Add object to list
        transportList.add(transport)
    end function

    function removeTransport(Transport transport) {
        // Remove object from list
        transportList.remove(transport)
    end function

end class

Demo

Client can use the individual Transport classes and the composite class objects the same way. The client does not know any difference between those two.

var bike: Bike = new Bike()
var plane: Plane = new Plane()
var car: Car = new Car()
var secondCar: Car = new Car()

TransportGroup transports = new TransportGroup()

// Add 4 transports
transports.addTransport(bike)
transports.addTransport(plane)
transports.addTransport(car)
transports.addTransport(secondCar)

// Perform operation of the list of 4 transports
transports.start()
transports.operate()
transports.stop()

// Remove plane and perform operations on other transports
transports.removeTransport(plane)

transports.start()
transports.operate()
transports.stop()

Output

The output of the demo above will be like below.

-----------------Output with 4 transports------------------

Starting Bike...
Starting Plane...
Starting Car...
Starting Car...
Riding Bike
Flying Plane
Driving Car
Driving Car
Stopping Bike...
Stopping Plane...
Stopping Car...
Stopping Car...

-----------------Output when plane is removed------------------

Starting Bike...
Starting Car...
Starting Car...
Riding Bike
Driving Car
Driving Car
Stopping Bike...
Stopping Car...
Stopping Car...

Code Implementations

Use the following links to check Composite pattern implementation in specific programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.