The Bridge Pattern is a structural design pattern that decouples an abstraction from its implementation, allowing them to vary independently. It provides a bridge between the abstraction and its implementation, enabling changes in one to not affect the other. To understand the Bridge Pattern better, let’s look at an example:
class Abstraction:
def __init__(self, implementation):
self.implementation = implementation
def operation(self):
return f"Abstraction: {self.implementation.operation_implementation()}"
class Implementation:
def operation_implementation(self):
pass
class ConcreteImplementationA(Implementation):
def operation_implementation(self):
return "ConcreteImplementationA operation"
class ConcreteImplementationB(Implementation):
def operation_implementation(self):
return "ConcreteImplementationB operation"
In this example, we have four classes: Abstraction
, Implementation
, ConcreteImplementationA
, and ConcreteImplementationB
.
-
The
Abstraction
class represents the abstraction or high-level component. It contains a reference to an object of theImplementation
class and defines the interface that clients will use. It delegates the implementation-specific details to theImplementation
object. -
The
Implementation
class represents the implementation or low-level component. It defines the interface for the implementation-specific operations. -
The
ConcreteImplementationA
andConcreteImplementationB
classes are concrete implementations of theImplementation
class. They provide specific implementations for the operations defined in theImplementation
class.
Here’s how you can use the Bridge Pattern:
implementation_a = ConcreteImplementationA()
abstraction_a = Abstraction(implementation_a)
print(abstraction_a.operation()) # Output: Abstraction: ConcreteImplementationA operation
implementation_b = ConcreteImplementationB()
abstraction_b = Abstraction(implementation_b)
print(abstraction_b.operation()) # Output: Abstraction: ConcreteImplementationB operation
In this code, we create instances of the concrete implementation classes (ConcreteImplementationA
and ConcreteImplementationB
). We then pass these instances to the Abstraction
constructor, creating two different abstractions (abstraction_a
and abstraction_b
). Finally, we call the operation()
method on each abstraction, which internally delegates the operation to the respective implementation object.
The Bridge Pattern allows the abstraction and implementation to vary independently. You can add new implementations without modifying the existing abstraction or vice versa. It promotes loose coupling and flexibility in your codebase, making it easier to maintain and extend.
Remember, the Bridge Pattern is just one of many design patterns that can be used to solve specific problems. It provides a way to separate the abstraction and implementation, allowing them to evolve independently.