Bridge Design Pattern (original) (raw)

Last Updated : 7 May, 2026

The Bridge Design Pattern is a structural design pattern that separates an abstraction from its implementation so that both can vary independently. It helps avoid tight coupling between abstraction and implementation, making the system more flexible and extensible.

There are 2 parts in Bridge design pattern.

  1. Abstraction
  2. Implementation

abstraction

UML Diagram

**Example: Consider a remote control system where a remote can operate different devices like a TV or a Light. Instead of creating separate remotes for each device, the Bridge Pattern separates the remote (abstraction) from the device (implementation). This allows the same remote to control different devices independently. You can extend remotes or add new devices without changing existing code.

abstraction-

In the Diagram:

Real-Life Applications

Bridge pattern is often used when you want to separate abstraction from its implementation to allow independent variation. Some common examples include:

Components

The bridge design pattern separates abstraction from implementation, allowing them to vary independently.

Working

The Bridge Pattern works by delegating implementation-specific work to a separate interface.

Uses

The Bridge Pattern is used when abstraction and implementation need to evolve independently.

Implementation Example

Vehicle is the abstraction, and Car and Bike are refined abstractions. The Workshop interface defines the implementation, with Produce and Assemble as concrete implementations. This allows vehicles and workshops to vary independently e.g., a Car can be produced and assembled without changing the Bike class.

C++ `

#include using namespace std;

class Workshop { public: virtual void work() = 0; };

class Produce : public Workshop { public: void work() override { cout << "Produced"; } };

class Assemble : public Workshop { public: void work() override { cout << " And"; cout << " Assembled." << endl; } };

class Vehicle { protected: Workshop* workShop1; Workshop* workShop2;

public: Vehicle(Workshop* workShop1, Workshop* workShop2) { this->workShop1 = workShop1; this->workShop2 = workShop2; } virtual void manufacture() = 0; };

class Car : public Vehicle { public: Car(Workshop* workShop1, Workshop* workShop2) : Vehicle(workShop1, workShop2) {} void manufacture() override { cout << "Car "; workShop1->work(); workShop2->work(); } };

class Bike : public Vehicle { public: Bike(Workshop* workShop1, Workshop* workShop2) : Vehicle(workShop1, workShop2) {} void manufacture() override { cout << "Bike "; workShop1->work(); workShop2->work(); } };

int main() { Vehicle* vehicle1 = new Car(new Produce(), new Assemble()); vehicle1->manufacture(); Vehicle* vehicle2 = new Bike(new Produce(), new Assemble()); vehicle2->manufacture(); return 0; }

Java

abstract class Vehicle { protected Workshop workShop1; protected Workshop workShop2;

protected Vehicle(Workshop workShop1, Workshop workShop2)
{
    this.workShop1 = workShop1;
    this.workShop2 = workShop2;
}

abstract public void manufacture();

}

// Refine abstraction 1 in bridge pattern class Car extends Vehicle { public Car(Workshop workShop1, Workshop workShop2) { super(workShop1, workShop2); }

@Override
public void manufacture()
{
    System.out.print("Car ");
    workShop1.work();
    workShop2.work();
}

}

// Refine abstraction 2 in bridge pattern class Bike extends Vehicle { public Bike(Workshop workShop1, Workshop workShop2) { super(workShop1, workShop2); }

@Override
public void manufacture()
{
    System.out.print("Bike ");
    workShop1.work();
    workShop2.work();
}

}

// Implementer for bridge pattern interface Workshop { abstract public void work(); }

// Concrete implementation 1 for bridge pattern class Produce implements Workshop { @Override public void work() { System.out.print("Produced"); } }

// Concrete implementation 2 for bridge pattern class Assemble implements Workshop { @Override public void work() { System.out.print(" And"); System.out.println(" Assembled."); } }

// Demonstration of bridge design pattern class BridgePattern { public static void main(String[] args) { Vehicle vehicle1 = new Car(new Produce(), new Assemble()); vehicle1.manufacture(); Vehicle vehicle2 = new Bike(new Produce(), new Assemble()); vehicle2.manufacture(); } }

Python

from abc import ABC, abstractmethod

class Workshop(ABC): @abstractmethod def work(self): pass

class Produce(Workshop): def work(self): print('Produced', end='')

class Assemble(Workshop): def work(self): print(' And', end='') print(' Assembled.')

class Vehicle(ABC): def init(self, workShop1, workShop2): self.workShop1 = workShop1 self.workShop2 = workShop2

@abstractmethod
def manufacture(self):
    pass

class Car(Vehicle): def manufacture(self): print('Car', end=' ') self.workShop1.work() self.workShop2.work()

class Bike(Vehicle): def manufacture(self): print('Bike', end=' ') self.workShop1.work() self.workShop2.work()

if name == 'main': vehicle1 = Car(Produce(), Assemble()) vehicle1.manufacture() vehicle2 = Bike(Produce(), Assemble()) vehicle2.manufacture()

JavaScript

class Workshop { work() { throw new Error('Method not implemented.'); } }

class Produce extends Workshop { work() { process.stdout.write('Produced'); } }

class Assemble extends Workshop { work() { process.stdout.write(' And'); console.log(' Assembled.'); } }

class Vehicle { constructor(workShop1, workShop2) { this.workShop1 = workShop1; this.workShop2 = workShop2; } manufacture() { throw new Error('Method not implemented.'); } }

class Car extends Vehicle { manufacture() { process.stdout.write('Car '); this.workShop1.work(); this.workShop2.work(); } }

class Bike extends Vehicle { manufacture() { process.stdout.write('Bike '); this.workShop1.work(); this.workShop2.work(); } }

const vehicle1 = new Car(new Produce(), new Assemble()); vehicle1.manufacture(); const vehicle2 = new Bike(new Produce(), new Assemble()); vehicle2.manufacture();

`

Output :

Car Produced And Assembled.
Bike Produced And Assembled.

Here we're producing and assembling the two different vehicles using Bridge design pattern.

Need of bridge design pattern

The Bridge pattern is an application of the old advice, "prefer composition over inheritance". It becomes handy when you must subclass different times in ways that are orthogonal with one another.
For Example, the above example can also be done something like this :

Without Bridge Design Pattern

bus

But the above solution has a problem. If you want to change the Bus class, then you may end up changing ProduceBus and AssembleBus as well and if the change is workshop specific then you may need to change the Bike class as well.

With Bridge Design Pattern

You can solve the above problem by decoupling the Vehicle and Workshop interfaces in the below manner.

vehicle

Advantages

The Bridge Pattern provides flexibility and better code organization by separating abstraction from implementation.

Disadvantages

Despite its benefits, the Bridge Pattern can introduce some complexity.

Also check