backend 5 min read • 2026-01-21
Understanding the Bridge Design Pattern
The Bridge pattern is a structural design pattern that decouples an abstraction from its implementation so that the two can vary independently. This pattern is particularly useful when you want to avoid a permanent binding between an abstraction and its implementation.
What is the Bridge Pattern?
The Bridge pattern uses composition instead of inheritance to separate the abstraction from its implementation. This allows you to change the implementation without affecting the abstraction, and vice versa.
When to Use the Bridge Pattern?
- When you want to avoid a permanent binding between an abstraction and its implementation
- When both the abstractions and their implementations should be extensible through subclassing
- When changes in the implementation of an abstraction should have no impact on clients
- When you want to hide the implementation of an abstraction completely from clients
Structure
The Bridge pattern involves:
- Abstraction: Defines the abstraction's interface and maintains a reference to an object of type Implementor
- RefinedAbstraction: Extends the abstraction interface
- Implementor: Defines the interface for implementation classes
- ConcreteImplementor: Implements the Implementor interface
Example in Java
// Implementor interface
interface DrawingAPI {
void drawCircle(double x, double y, double radius);
}
// Concrete Implementor 1
class DrawingAPI1 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API1.circle at %.2f:%.2f radius %.2f%n", x, y, radius);
}
}
// Concrete Implementor 2
class DrawingAPI2 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API2.circle at %.2f:%.2f radius %.2f%n", x, y, radius);
}
}
// Abstraction
abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI drawingAPI) {
this.drawingAPI = drawingAPI;
}
public abstract void draw();
}
// Refined Abstraction
class Circle extends Shape {
private double x, y, radius;
public Circle(double x, double y, double radius, DrawingAPI drawingAPI) {
super(drawingAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
}
// Usage
public class BridgePatternDemo {
public static void main(String[] args) {
Shape circle1 = new Circle(1, 2, 3, new DrawingAPI1());
Shape circle2 = new Circle(5, 7, 11, new DrawingAPI2());
circle1.draw();
circle2.draw();
}
}
Benefits
- Decoupling: Separates the interface from the implementation
- Flexibility: Allows you to change implementations at runtime
- Extensibility: Easy to add new abstractions and implementations independently
- Hiding Implementation Details: Clients only see the abstraction interface
Real-World Applications
- GUI frameworks where platform-specific implementations are separated from the UI code
- Database drivers where the database API is separated from the database implementation
- Remote procedure calls where the communication protocol is separated from the service implementation
Conclusion
The Bridge pattern is a powerful tool for creating flexible, maintainable code. By separating abstraction from implementation, you can build systems that are easier to extend and modify without affecting existing code.