Bridge: Separating Abstraction From Implementation
The Problem It Solves
Remotes and devices both vary. Basic remote, advanced remote; TV, radio. Inheritance across both axes at once forces the cross-product: BasicTvRemote, AdvancedTvRemote, BasicRadioRemote, AdvancedRadioRemote — 2×2 = 4 classes, 3×3 = 9, m×n grows multiplicatively, every new device re-touches every remote class. Bridge splits the axes and joins them with composition: abstractions hold a reference to an implementor interface; each axis extends independently.
INHERITANCE ACROSS TWO AXES BRIDGED
Remote Remote ───── holds ────► Device ◁ interface
├── TvRemote ├── Tv
│ └── AdvancedTvRemote └── Radio
└── RadioRemote Abstraction side (m classes) ×
└── AdvancedRadioRemote Implementor side (n classes) = m + n total,
4 classes now; 3×3 = 9 later new axis entries never touch the other side
Mechanics
// IMPLEMENTOR AXIS — how operations reach a device:
interface Device {
void setVolume(int pct);
int volume();
}
class Tv implements Device { /* real impl */ }
class Radio implements Device { /* real impl */ }
// ABSTRACTION AXIS — what users can do:
abstract class Remote {
protected final Device device; // THE bridge reference
Remote(Device d) { this.device = d; }
void volumeUp() { device.setVolume(device.volume() + 10); }
}
class AdvancedRemote extends Remote { // extends ONLY its own axis
AdvancedRemote(Device d) { super(d); }
void mute() { device.setVolume(0); }
}
// any pairing works — assembled at runtime:
new AdvancedRemote(new Tv());
new BasicRemote(new Radio());
Remote subclasses never subclass devices; they call them through the Device contract. The two hierarchies vary independently forever.
Recognizing Bridge-Worthy Designs
The signal is two independent “how it varies” questions:
| Abstraction axis | Implementor axis |
|---|---|
| Message types (alert/report) | Senders (email/SMS/push) |
| Shapes | Renderers (screen/vector/printer) |
| Payment flows | Gateways |
If you draw a hierarchy and realize every level multiplies by another dimension, that is the refactor point.
Mechanics of Migration (from inheritance tangle to bridge)
- Extract the lower axis into an interface (
Device). - Replace parent-class fields in concrete combos with that interface.
- Delete cross-product classes; wire pairings in composition root.
- Class count drops from m×n to m+n — the arithmetic payoff worth stating in interviews.
vs Strategy vs Adapter
| Pattern | Distinction |
|---|---|
| Bridge | Structural split of two stable axes, decided at construction |
| Strategy | Behavior swapped per operation/lifecycle; single axis |
| Adapter | Makes an existing incompatible thing fit; no two-axis design intent |
Bridge is often described as strategy applied structurally at design time — close enough for interviews if the axis-independence point lands.
Trade-offs & Pitfalls
- Gains: linear growth on both axes; runtime pairing; each side compiles independently.
- Costs: extra indirection layer; pointless when one axis is frozen (a second dimension that never varies needs no bridge — YAGNI).
- Over-application warning: single-varying-axis designs dressed as bridges add ceremony without removing explosion risk.
Interview Framing
- The m×n → m+n arithmetic plus one concrete axis-pair example (“message × sender”) is the complete expected answer.
Premium Content
Unlock Bridge and all premium lessons with a subscription.
From ₹199.99/year — See plans