Bridge pattern is used to separate/decouple the abstraction from the implementation, so that we can change those separately. The bridge pattern works as the communication for those two separate parts.
NOTES
In this article, we discuss the implementation of the Bridge Pattern in Python.
See the Bridge in other languages in the “Other Code Implementations” section. Or, use the link below to check the details of the Bridge Pattern-
Implementation
Here is a simple example of Bridge pattern implemenation in Python-
from typing import Protocol
from abc import ABC, abstractmethod
# Plugin interface using Protocol
class PluginI(Protocol):
def plugin_operation_1(self) -> None:
...
# First plugin
class Plugin1:
def plugin_operation_1(self) -> None:
print("Plugin 1: operation 1")
# Second plugin
class Plugin2:
def plugin_operation_1(self) -> None:
print("Plugin 2: operation 1")
# Module interface using Protocol
class Module(ABC):
def __init__(self, plugin: PluginI) -> None:
self.plugin = plugin
@abstractmethod
def module_operation_1(self) -> None:
pass
# First module
class Module1(Module):
def __init__(self, plugin: PluginI) -> None:
self.plugin = plugin
def module_operation_1(self) -> None:
print("Module 1: operation 1")
self.plugin.plugin_operation_1()
# Second module
class Module2(Module):
def __init__(self, plugin: PluginI) -> None:
self.plugin = plugin
def module_operation_1(self) -> None:
print("Module 2: operation 1")
self.plugin.plugin_operation_1()
# Demo Usage
def main():
module1 = Module1(Plugin2())
module1.module_operation_1()
if __name__ == "__main__":
main()
PythonHere is the output of the above implementation-
Module 1: operation 1
Plugin 2: operation 1
PlaintextExamples
Check the following examples of Bridge pattern implementation-
Example #1: UI Elements
In this exmple we have main modules for different UI elements, like- Button, Table, Input. And we have compnents for different colors.
Let’s see how can we separat the modules from the colors, and use the colors for the component, when we need it.
Color Interface
from abc import ABC, abstractmethod
# Color interface
class Color(ABC):
@abstractmethod
def set_color(self) -> None:
pass
PythonRed [Color Schema]
# Red color class
class Red(Color):
def set_color(self) -> None:
print("Setting proper color for Red color schema")
PythonGreen [Color Schema]
# Green color class
class Green(Color):
def set_color(self) -> None:
print("Setting proper color for Green color schema")
PythonBlue [Color Schema]
# Blue color class
class Blue(Color):
def set_color(self) -> None:
print("Setting proper color for Blue color schema")
PythonUI Element Interface
# UIElement abstract class
class UIElement(ABC):
def __init__(self, color: Color) -> None:
self.color = color
@abstractmethod
def print_element(self) -> None:
pass
PythonButton [UI Element]
# Button class
class Button(UIElement):
def print_element(self) -> None:
self.color.set_color()
print("Printing Button")
PythonInput [UI Element]
# Input class
class Input(UIElement):
def print_element(self) -> None:
self.color.set_color()
print("Printing Input")
PythonTable [UI Element]
# Table class
class Table(UIElement):
def print_element(self) -> None:
self.color.set_color()
print("Printing Table")
PythonDemo
# Demo Usage
def main():
table = Table(Red())
table.print_element()
input_element = Input(Green())
input_element.print_element()
button = Button(Blue())
button.print_element()
button2 = Button(Red())
button2.print_element()
if __name__ == "__main__":
main()
PythonOutput
Output will be as follows-
Setting proper color for Red color schema
Printing Table
Setting proper color for Green color schema
Printing Input
Setting proper color for Blue color schema
Printing Button
Setting proper color for Red color schema
Printing Button
PlaintextExample #2: Transport Seat
In this example we have different type of seats and different type of transports. Let’s see how can we dynamically use the same seat compnent classes for different type of transports.
Seat Interface
from typing import Protocol
# Seat interface using Protocol
class Seat(Protocol):
def select_seat(self) -> None:
pass
PythonBusiness Class Seat [Seat Type]
# BusinessClassSeat class
class BusinessClassSeat:
def select_seat(self) -> None:
print("Select a Business class seat")
PythonEconomy Class Seat [Seat Type]
# EconomyClassSeat class
class EconomyClassSeat:
def select_seat(self) -> None:
print("Select an Economy class seat")
PythonTransport Interface
from abc import ABC, abstractmethod
# Transport abstract class
class Transport(ABC):
def __init__(self, seat: Seat) -> None:
self.seat = seat
@abstractmethod
def select_transport(self) -> None:
pass
PythonPlane [Transport]
# Plane class
class Plane(Transport):
def select_transport(self) -> None:
print("Plane selected for transport")
self.seat.select_seat()
PythonTrain [Transport]
# Train class
class Train(Transport):
def select_transport(self) -> None:
print("Train selected for transport")
self.seat.select_seat()
PythonDemo
# Demo usage
def main():
plane = Plane(BusinessClassSeat())
plane.select_transport()
plane2 = Plane(EconomyClassSeat())
plane2.select_transport()
train = Train(EconomyClassSeat())
train.select_transport()
if __name__ == "__main__":
main()
PythonOutput
We will get the following output.
Plane selected for transport
Select an Business class seat
Plane selected for transport
Select an Economy class seat
Train selected for transport
Select an Economy class seat
PlaintextSource Code
Use the following link to get the source code:
Other Code Implementations
Use the following links to check the implementation of the bridge pattern in other programming languages.