designpatterns/structural

They’re connected by a bridge, but can vary independently.

The Bridge Pattern is a structural design pattern that decouples an abstraction from its implementation so they can evolve independently.

You split something into two separate hierarchies:

  • Abstraction (what you want to do)
  • Implementation (how you do it)

Bridge Pattern vs Strategy Pattern

So many people confuse the Bridge with the SA03.10 - Strategy Pattern. So structurally (in code), they can look very similar.
Remember that a pattern is more than just a certain way to structure your classes. It may also communicate intent and a problem being addressed.

The key difference is intent (the reason why you use the pattern).

PatternIntent / Purpose
BridgeTo separate abstraction from implementation so they can evolve independently. You care about decoupling layers.
StrategyTo change the behavior (algorithm) at runtime. You care about switching algorithms or policies flexibly.
  • Bridge → “I want different remotes working with different devices.” (separate families)
  • Strategy → “I want to switch sorting algorithms dynamically.” (swap behavior)

Structure

When to Use

When you want to separate abstraction from implementation.
When both the abstraction and implementation may change independently.
When you want to avoid a class explosion caused by combining many variations.

Real World Examples

  • Remote controls (for various devices)
  • UI themes (abstraction) + platforms (implementation)
  • Shapes (abstraction) + drawing APIs (implementation)
  • Cross-platform drivers (abstraction) + operating systems (implementation)

Code Examples

// Device interface (Implementor)
interface Device {
    void turnOn();
    void turnOff();
}
 
// Concrete Implementor: TV
class TV implements Device {
    public void turnOn() {
        System.out.println("TV is turned ON.");
    }
 
    public void turnOff() {
        System.out.println("TV is turned OFF.");
    }
}
 
// Concrete Implementor: DVD Player
class DVDPlayer implements Device {
    public void turnOn() {
        System.out.println("DVD Player is turned ON.");
    }
 
    public void turnOff() {
        System.out.println("DVD Player is turned OFF.");
    }
}
 
// Abstraction
abstract class RemoteControl {
    protected Device device;
 
    public RemoteControl(Device device) {
        this.device = device;
    }
 
    public abstract void turnOnDevice();
    public abstract void turnOffDevice();
}
 
// Refined Abstraction
class BasicRemote extends RemoteControl {
    public BasicRemote(Device device) {
        super(device);
    }
 
    public void turnOnDevice() {
        System.out.print("BasicRemote: ");
        device.turnOn();
    }
 
    public void turnOffDevice() {
        System.out.print("BasicRemote: ");
        device.turnOff();
    }
}
 
// Main class to run the demo
public class BridgePatternDemo {
    public static void main(String[] args) {
        Device tv = new TV();
        Device dvd = new DVDPlayer();
 
        RemoteControl tvRemote = new BasicRemote(tv);
        RemoteControl dvdRemote = new BasicRemote(dvd);
 
        tvRemote.turnOnDevice();
        dvdRemote.turnOnDevice();
 
        tvRemote.turnOffDevice();
        dvdRemote.turnOffDevice();
    }
}