Low Level Design
Bridge Pattern — Decouple Abstraction from Implementation
How the Bridge pattern prevents class explosion by separating what an object does from how it does it, letting both hierarchies evolve independently.
What is the Bridge Pattern?#
The Bridge is a structural design pattern that decouples an abstraction from its implementation so that the two can vary independently.
It separates what an object does (abstraction) from how it does it (implementation).
You reach for Bridge when:
- A class has multiple dimensions of variation (e.g., shapes × rendering APIs, devices × remotes)
- You want to avoid class explosion — the combinatorial growth of subclasses when two hierarchies are combined
- Abstraction and implementation should both be extensible through subclassing
Real-World Analogy#
A Remote Control is the abstraction. The Device (TV, Radio, Projector) is the implementation.
Without Bridge, you'd need:
- TVBasicRemote, TVAdvancedRemote
- RadioBasicRemote, RadioAdvancedRemote
- ProjectorBasicRemote, ProjectorAdvancedRemote
That's 6 classes for 2 remotes × 3 devices. Add one more device → 2 more classes. The combination explodes.
With Bridge, you have 2 Remote classes + 3 Device classes = 5 total, and any remote works with any device.
Class Diagram#
Violation Code — The Problem#
// ❌ Tight coupling — one class per combination
class TVRemote {
public void on() { System.out.println("TV ON"); }
public void off() { System.out.println("TV OFF"); }
}
class RadioRemote {
public void on() { System.out.println("Radio ON"); }
public void off() { System.out.println("Radio OFF"); }
}
// Now add AdvancedRemote... 2 more classes.
// Now add Projector... 2 more classes.
// N remotes × M devices = N×M classes ❌
Issues:
- Class explosion — adding any new device or remote type multiplies the number of classes
- No flexibility — remote and device are tightly bound in one class
- Poor maintainability — changes in one class cascade everywhere
Enhanced Code — Bridge Pattern#
// Implementation interface
public interface Device {
void on();
void off();
}
// Concrete implementations
public class TV implements Device {
public void on() { System.out.println("TV: ON"); }
public void off() { System.out.println("TV: OFF"); }
}
public class Radio implements Device {
public void on() { System.out.println("Radio: ON"); }
public void off() { System.out.println("Radio: OFF"); }
}
// Abstraction — holds a reference to implementation
public abstract class Remote {
protected Device device;
public Remote(Device device) { this.device = device; }
public void on() { device.on(); }
public void off() { device.off(); }
}
// Refined abstractions — extend the remote without knowing the device
public class BasicRemote extends Remote {
public BasicRemote(Device device) { super(device); }
// inherits on() / off() as-is
}
public class AdvancedRemote extends Remote {
public AdvancedRemote(Device device) { super(device); }
public void mute() {
System.out.println("Muting device...");
device.off();
device.on();
}
}
// Usage — any remote works with any device
public class Main {
public static void main(String[] args) {
Remote tvRemote = new BasicRemote(new TV());
Remote radioAdvanced = new AdvancedRemote(new Radio());
tvRemote.on(); // TV: ON
radioAdvanced.on(); // Radio: ON
((AdvancedRemote) radioAdvanced).mute();
}
}
Adding a Projector device → one new class. Adding a VoiceRemote → one new class. No existing code is touched.
Common LLD Problems Using Bridge Pattern#
1. Remote Control System#
- Decouple Remote abstraction (Basic, Advanced) from Device implementations (TV, Radio, Projector).
2. Payment System#
- Separate PaymentMethod abstraction (CreditCard, UPI) from PaymentGateway implementation (PayPal, Stripe, Razorpay).
3. Drawing / Graphics Application#
- Split Shape abstraction (Circle, Rectangle) from RenderingAPI implementation (OpenGL, DirectX, Canvas).
4. Notification System#
- Decouple Notification type (Email, SMS, Push) from MessageSender implementation (SendGrid, Twilio, Firebase).
5. Document Management#
- Separate Document abstraction (PDF, Word, Spreadsheet) from Storage implementation (Local, S3, Google Drive).
6. Audio Player#
- Bridge between MediaPlayer abstraction (BasicPlayer, AdvancedPlayer) and AudioFormat implementation (MP3, WAV, FLAC).
7. Report Generation#
- Abstract Report (Summary, Detailed) from ExportFormat implementation (PDF, Excel, HTML).
8. E-commerce Discount System#
- Separate Discount abstraction (Seasonal, Festival, Loyalty) from CalculationStrategy implementation.
Bridge vs Strategy#
Both involve composition over inheritance, but:
| Bridge | Strategy | |
|---|---|---|
| Purpose | Decouple two evolving hierarchies | Swap algorithms at runtime |
| Dimensions | Two independent class hierarchies | One behavior dimension |
| Design time | Structural relationship | Behavioral substitution |
| References | Links |
|---|---|
| Article Reference | Refactoring Guru — Bridge |