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:
Here is a Python implementation of the Bridge Pattern.
Example:
- You have shapes: Circle, Square
- You have rendering APIs: OpenGL, DirectX, Vulkan
- Abstraction – High-level control logic (e.g., Shape)
- Implementation – Low-level platform-specific details (e.g., Renderer)
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.
Enjoy...

No comments:
Post a Comment