Overview
The Bridge pattern separates an abstraction from its implementation so both can vary independently. Instead of a class hierarchy with every combination (EmailAlert, SmsAlert, UrgentEmailAlert, UrgentSmsAlert...), you have an abstraction hierarchy (Alert, UrgentAlert) that holds a reference to an implementation hierarchy (Channel: Email, SMS).
Bridge prevents the 'm x n' class explosion when two dimensions vary. It looks structurally like Strategy (composition with an interface), but the intent differs: Bridge is designed up front to decouple two orthogonal hierarchies that both evolve.
A basic remote and an advanced remote (abstractions) can both control a TV or a radio (implementations). New remotes and new devices can be added independently because they communicate through a standard device interface.
When to use it
- Two independent dimensions of variation (shape x renderer, message type x channel).
- Implementations should be switchable at runtime.
- You want to avoid a combinatorial subclass explosion.
Where it shows up in interviews
Recognize it when: types x platforms, messages x channels.
- Design a notification system with message types and channels
- Design a drawing app with shapes and renderers
Where it is used in real software
Your code uses the JDBC abstraction while vendor drivers are the implementation side.
Logging API (abstraction) bridged to Logback or Log4j (implementation).
UI toolkits separate widgets from rendering backends (OpenGL, Metal, Skia).
Key terms
- Abstraction
- High-level control layer (Alert, Shape).
- Refined abstraction
- Variants of the abstraction (UrgentAlert).
- Implementor
- Low-level interface (Channel, Renderer).
- Concrete implementor
- EmailChannel, SvgRenderer.
How it works, step by step
- 1Identify the two dimensions
What varies independently?
- 2Define the implementor interface
Primitive operations: send(to, text).
- 3Define the abstraction holding an implementor
Alert(channel).
- 4Extend each side independently
New alert types; new channels.
- 5Combine at runtime
new UrgentAlert(new SmsChannel()).
Class count comparison
3 alert types x 4 channels
| Design | Classes | Adding a 5th channel |
|---|---|---|
| Subclass per combination | 12 | +3 classes |
| Bridge | 3 + 4 = 7 | +1 class |
NOWDesign: Subclass per combination | Classes: 12 | Adding a 5th channel: +3 classes
Bridge turns multiplication into addition.
Implementation
// Implementorinterface Channel { send(to: string, text: string): void }class EmailChannel implements Channel { send(to: string, t: string) { console.log("email", to, t); } }class SmsChannel implements Channel { send(to: string, t: string) { console.log("sms", to, t.slice(0, 160)); } } // Abstractionabstract class Alert { constructor(protected channel: Channel) {} abstract notify(to: string, message: string): void;} class InfoAlert extends Alert { notify(to: string, message: string) { this.channel.send(to, message); }} class UrgentAlert extends Alert { notify(to: string, message: string) { this.channel.send(to, `URGENT: ${message}`); this.channel.send(to, `Reminder: ${message}`); // urgent policy: send twice }} new UrgentAlert(new SmsChannel()).notify("+15550100", "Server down");new InfoAlert(new EmailChannel()).notify("[email protected]", "Deploy complete");Complexity and performance
vs m x n.
Negligible.
Trade-offs
Bridge requires identifying the two dimensions early; applied too soon it adds indirection.
The implementor must expose primitives general enough for all abstractions.
Variants and related techniques
Similar structure; Strategy swaps an algorithm, Bridge separates two evolving hierarchies.
Adapter fixes incompatibility after the fact; Bridge is designed in advance.
Common mistakes
- Using Bridge with only one dimension.
Fix: A single interface (Strategy) is enough.
- Leaking implementor details into abstractions.
Fix: Keep implementors to primitive operations.
Interview questions
What problem does Bridge solve?
Class explosion when two dimensions vary independently. It splits them into two hierarchies connected by composition so each can grow without multiplying classes.
How is Bridge different from Strategy?
Structurally similar, but Bridge's intent is separating an abstraction hierarchy from an implementation hierarchy, both of which have subclasses, while Strategy swaps one algorithm inside a context.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| Messages (info, urgent) x channels (email, SMS, push) | Medium | Two hierarchies. |
| Shapes x renderers (SVG, canvas) | Medium | Primitive operations. |