CLOSE
Updated on 02 Sep, 202515 mins read 127 views

As we know that Structural Design Patterns are concerned with the composition of classes and objects. They focus on how to assemble classes and objects into larger structures while keeping these structures flexible and efficient. Bridge Pattern is one of the most important structural design pattern.

What is the Bridge Pattern?

The Bridge pattern separates an object's abstraction (high-level part) from its implementation (low-level operations).

Instead of binding abstraction and implementation permanently, Bridges uses composition to connect them, making the system more flexible.

[info title="Key Idea" type=info]Prefer composition over inheritance when you need to decouple abstraction from implementation.[/info]

Problem Without Bridge

Suppose we have different Car types (e.g., Sedan, SUV, Hatchback) and different Engine types (e.g., Petrol Engine, Diesel Engine, Electric Engine).

If we directly use inheritance, we will need a class for each combination:

  • SedanWithPetrolEngine
  • SedanWithDieselEngine
  • SedanWIthElectricEngine
  • SUVWithPetrolEngine
  • SUVWithDieselEngine
  • SUVWithElectricEngine

And if tomorrow we add CNG Engine, we will need two more classes.

This leads to class explosion -> difficult to manage and extend.

Example Code Without Bridge:

#include <iostream>
using namespace std;

// Sedan with Petrol Engine
class SedanPetrol {
public:
    void drive() { cout << "Driving Sedan with Petrol Engine\n"; }
};

// Sedan with Diesel Engine
class SedanDiesel {
public:
    void drive() { cout << "Driving Sedan with Diesel Engine\n"; }
};

// SUV with Petrol Engine
class SUVPetrol {
public:
    void drive() { cout << "Driving SUV with Petrol Engine\n"; }
};

// SUV with Diesel Engine
class SUVDiesel {
public:
    void drive() { cout << "Driving SUV with Diesel Engine\n"; }
};

int main() {
    SedanPetrol sedanPetrol;
    sedanPetrol.drive();

    SUVDiesel suvDiesel;
    suvDiesel.drive();

    return 0;
}

Output:

Driving Sedan with Petrol Engine
Driving SUV with Diesel Engine

Problems:

  1. Class Explosion: For n car types * m engine types, we get n*m classes.
  2. Tight Coupling: Car and engine are bound together, can't reuse independently.
  3. Hard to Extend: Adding a new engine requires modifying or creating many classes.

Solution With Bridge Pattern

With a Bridge Pattern, we separate:

  • Abstraction (Car) – Represents different card types  (Sedan, SUV).
  • Implementor (Engine) – Represents different engine types (Petrol, Diesel, Electric).

Cars uses engines via composition, not inheritance.

#include <iostream>
using namespace std;

// Implementor (Engine Interface)
class Engine {
public:
    virtual void start() = 0;
    virtual ~Engine() = default;
};

// Concrete Implementors
class PetrolEngine : public Engine {
public:
    void start() override { cout << "Starting Petrol Engine\n"; }
};

class DieselEngine : public Engine {
public:
    void start() override { cout << "Starting Diesel Engine\n"; }
};

class ElectricEngine : public Engine {
public:
    void start() override { cout << "Starting Electric Engine\n"; }
};

// Abstraction (Car)
class Car {
protected:
    Engine* engine;  // Bridge
public:
    Car(Engine* eng) : engine(eng) {}
    virtual void drive() = 0;
    virtual ~Car() = default;
};

// Refined Abstractions
class Sedan : public Car {
public:
    Sedan(Engine* eng) : Car(eng) {}
    void drive() override {
        cout << "Sedan is driving... ";
        engine->start();
    }
};

class SUV : public Car {
public:
    SUV(Engine* eng) : Car(eng) {}
    void drive() override {
        cout << "SUV is driving... ";
        engine->start();
    }
};

int main() {
    PetrolEngine petrol;
    DieselEngine diesel;
    ElectricEngine electric;

    Sedan sedan1(&petrol);
    Sedan sedan2(&electric);

    SUV suv1(&diesel);
    SUV suv2(&petrol);

    sedan1.drive();
    sedan2.drive();
    suv1.drive();
    suv2.drive();

    return 0;
}

Output:

Sedan is driving... Starting Petrol Engine
Sedan is driving... Starting Electric Engine
SUV is driving... Starting Diesel Engine
SUV is driving... Starting Petrol Engine

Benefits of Bridge Here

  • No class explosion: Only n + m classes (Cars + Engines) instead of n * m.
  • Loose coupling: Car types and Engines types are independently.
  • Easy to extend: Adding a new engine or car type requires only one new class.

Leave a comment

Your email address will not be published. Required fields are marked *