Friday, July 3, 2026

Bridge Pattern using Python...

Bridge Pattern is a structural design pattern that decouples an abstraction from its implementation, allowing both to evolve independently.

Why it exists (The Problem)When you have classes that can vary in two or more independent dimensions, simple inheritance leads to a combinatorial explosion of subclasses.
Example:
  • You have shapes: Circle, Square
  • You have rendering APIs: OpenGL, DirectX, Vulkan
Using inheritance, you end up with: CircleOpenGL, CircleDirectX, SquareOpenGL, etc. — and it gets worse as you add more shapes or renderers.Solution: Bridge PatternThe pattern splits the class into two hierarchies:
  1. Abstraction – High-level control logic (e.g., Shape)
  2. Implementation – Low-level platform-specific details (e.g., Renderer)
These two hierarchies are connected via a bridge (composition instead of inheritance).
Here is a Python implementation of the Bridge Pattern.



from
abc import ABC, abstractmethod

# ==================== Implementor 1: Color ====================
class Color(ABC):
@abstractmethod
def get_color(self) -> str:
pass

@abstractmethod
def paint(self):
pass


class Red(Color):
def get_color(self) -> str:
return "Red"

def paint(self):
print("Painting the vehicle in vibrant Red...")


class Black(Color):
def get_color(self) -> str:
return "Black"

def paint(self):
print("Painting the vehicle in deep Black...")


# ==================== Implementor 2: Gear ====================
class Gear(ABC):
@abstractmethod
def get_type(self) -> str:
pass

@abstractmethod
def shift(self):
pass


class ManualGear(Gear):
def get_type(self) -> str:
return "Manual"

def shift(self):
print("Shifting gears manually...")


class AutoGear(Gear):
def get_type(self) -> str:
return "Automatic"

def shift(self):
print("Shifting gears automatically...")


# ==================== Abstraction: Vehicle ====================
class Vehicle(ABC):
def __init__(self, color: Color, gear: Gear):
self.color = color # Bridge to Color implementor
self.gear = gear # Bridge to Gear implementor

@abstractmethod
def display(self):
pass

def paint_vehicle(self):
self.color.paint()

def change_gear(self):
self.gear.shift()


# ==================== Refined Abstractions ====================
class SmallCar(Vehicle):
def display(self):
print(f"=== Small Car ===")
print(f"Color: {self.color.get_color()}")
print(f"Gear: {self.gear.get_type()}")
self.paint_vehicle()
self.change_gear()
print("Driving smoothly in the city...\n")


class Truck(Vehicle):
def display(self):
print(f"=== Truck ===")
print(f"Color: {self.color.get_color()}")
print(f"Gear: {self.gear.get_type()}")
self.paint_vehicle()
self.change_gear()
print("Hauling heavy load on the highway...\n")


# ==================== Client Code ====================
if __name__ == "__main__":
# Create implementors
red = Red()
black = Black()
auto = AutoGear()
manual = ManualGear()

# Create vehicles with different combinations (independent variation)
print("Creating vehicles using Bridge Pattern:\n")

car1 = SmallCar(red, auto)
car1.display()

car2 = Truck(black, manual)
car2.display()

car3 = SmallCar(black, auto)
car3.display()

Here's what the above solution would look like without the Bridge Pattern - look at the image below.

Look at the left-side hierarchy of classes. With more and more attributes, the inheritance tree would have exploded.

So... comes the Bridge Pattern - a nice solution without so many classes as depicted in the right hierarchy of classes.





I hope I have clarified the Bridge Pattern clearly.

Enjoy...