Skip to content

Bridge Pattern ​

Overview ​

The Bridge Pattern is a structural design pattern that decouples an abstraction from its implementation so that the two can vary independently. Instead of binding an abstraction to a specific implementation at compile time, the Bridge Pattern uses composition to delegate work to an implementation object.


Learning Objectives ​

  • Understand the intent of the Bridge Pattern.
  • Learn how to separate abstractions from implementations using composition.
  • Implement Bridge in Java with UML and real-world examples.
  • Differentiate Bridge from Adapter and Strategy patterns.
  • Apply Bridge to avoid class explosion in systems with multiple dimensions of variation.

Why Bridge Matters ​

  • Scalability: Prevents combinatorial explosion of subclasses.
  • Flexibility: Abstraction and implementation can evolve independently.
  • Maintainability: Changes in implementation don’t affect the abstraction layer.

Example: A drawing application supporting multiple shapes (Circle, Square) and rendering APIs (OpenGL, DirectX). Without Bridge, you’d need a class for each combination (OpenGLCircle, DirectXCircle), but with Bridge, you can mix and match dynamically.


Key Concepts ​

  • Abstraction: Defines the high-level control interface.
  • Refined Abstraction: Extends the abstraction’s interface.
  • Implementor: Defines the low-level interface.
  • Concrete Implementor: Provides implementation-specific behavior.

UML Diagram ​

        Abstraction
        + operation()
             |
             v
   RefinedAbstraction
             |
             v
       Implementor <----> ConcreteImplementorA
                        <----> ConcreteImplementorB

Code Example: Drawing Shapes with Bridge ​

Implementor ​

java
public interface DrawingAPI {
    void drawCircle(int x, int y, int radius);
}

Concrete Implementors ​

java
public class OpenGLAPI implements DrawingAPI {
    @Override
    public void drawCircle(int x, int y, int radius) {
        System.out.println("OpenGL drawing circle at (" + x + "," + y + ") with radius " + radius);
    }
}

public class DirectXAPI implements DrawingAPI {
    @Override
    public void drawCircle(int x, int y, int radius) {
        System.out.println("DirectX drawing circle at (" + x + "," + y + ") with radius " + radius);
    }
}

Abstraction ​

java
public abstract class Shape {
    protected DrawingAPI drawingAPI;

    protected Shape(DrawingAPI drawingAPI) {
        this.drawingAPI = drawingAPI;
    }

    public abstract void draw();
}

Refined Abstraction ​

java
public class Circle extends Shape {
    private int x, y, radius;

    public Circle(int x, int y, int radius, DrawingAPI drawingAPI) {
        super(drawingAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    @Override
    public void draw() {
        drawingAPI.drawCircle(x, y, radius);
    }
}

Client Code ​

java
public class BridgeDemo {
    public static void main(String[] args) {
        Shape circle1 = new Circle(1, 2, 5, new OpenGLAPI());
        Shape circle2 = new Circle(3, 4, 10, new DirectXAPI());

        circle1.draw(); // OpenGL drawing circle at (1,2) with radius 5
        circle2.draw(); // DirectX drawing circle at (3,4) with radius 10
    }
}

Real-World Examples ​

  • JDBC Drivers: JDBC provides the abstraction, while drivers (MySQL, PostgreSQL) are concrete implementors.
  • UI Frameworks: Separate UI abstraction (buttons, windows) from platform-specific rendering.
  • Logging Frameworks: Logging API (abstraction) + different logging backends (Log4j, SLF4J).

Relation to Other Patterns ​

  • Adapter: Makes unrelated interfaces compatible. Bridge separates abstraction from implementation by design.
  • Strategy: Focuses on interchangeable algorithms, while Bridge focuses on decoupling abstraction and implementation.
  • Decorator: Adds behavior dynamically, while Bridge separates hierarchies.

Practice Exercises ​

  • Easy: Implement a Notification abstraction with different channels (Email, SMS) as implementors.
  • Medium: Build a RemoteControl abstraction with devices (TV, Radio) as implementors.
  • Hard: Design a cross-platform DocumentEditor where formatting and content management are decoupled using Bridge.

Conclusion ​

The Bridge Pattern provides flexibility by decoupling abstractions from implementations, enabling independent evolution of both. By applying Bridge, you reduce class explosion and increase maintainability.

Next Step: Explore Flyweight Pattern or revisit the Design Patterns Hub.


Connect: LinkedIn

© 2025 Official CTO. All rights reserved.