The Bridge Design Pattern: Decouple Abstraction from Implementation
Master the Bridge Pattern in Java. Learn how to avoid class explosion by separating abstraction and implementation hierarchies.
Moshiour Rahman
Advertisement
The Problem: Class Explosion
Imagine you have Shapes (Circle, Square) and Colors (Red, Blue).
With inheritance, you’d have:
RedCircle,BlueCircleRedSquare,BlueSquare
Now add Green. You need 2 more classes.
Add Triangle. You need 3 more classes.
2 shapes × 3 colors = 6 classes
10 shapes × 10 colors = 100 classes 💥
This is the “Cartesian product problem.”
The Solution: The Bridge Pattern
The Bridge Pattern separates abstraction (Shape) from implementation (Color) so they can vary independently.
Real-Life Analogy: TV Remote 📺
- Remote (Abstraction): Buttons like “Volume Up”, “Channel Change”
- TV (Implementation): Sony, Samsung, LG
The same remote works with any TV brand because it uses a standard interface (IR signal, HDMI-CEC).
You don’t need a separate remote for every TV model.
Visualizing the Pattern

Implementation
1. The Implementation Interface
// The "Implementation" side (Color)
public interface Color {
void applyColor();
}
2. Concrete Implementations
public class Red implements Color {
@Override
public void applyColor() {
System.out.print("Red ");
}
}
public class Blue implements Color {
@Override
public void applyColor() {
System.out.print("Blue ");
}
}
3. The Abstraction
// The "Abstraction" side (Shape)
public abstract class Shape {
protected Color color; // Bridge to implementation
public Shape(Color color) {
this.color = color;
}
public abstract void draw();
}
4. Refined Abstractions
public class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
public void draw() {
color.applyColor();
System.out.println("Circle");
}
}
public class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
public void draw() {
color.applyColor();
System.out.println("Square");
}
}
Usage
// Composition, not inheritance
Shape redCircle = new Circle(new Red());
redCircle.draw(); // Output: Red Circle
Shape blueSquare = new Square(new Blue());
blueSquare.draw(); // Output: Blue Square
// Add new color? Just add one class!
class Green implements Color { ... }
// Add new shape? Just add one class!
class Triangle extends Shape { ... }
// No explosion: 10 shapes + 10 colors = 20 classes (not 100!)
In The Wild (Real World Examples)
1. JDBC Driver
Abstraction: Connection, Statement, ResultSet
Implementation: MySQL, PostgreSQL, Oracle drivers
// Same code works with any database
Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
// Implementation is bridged at runtime
2. AWT/Swing Peer Architecture
Java’s GUI framework separates:
- Abstraction:
Button,TextField(platform-independent) - Implementation: Platform-specific peer (Windows, Mac, Linux)
Bridge vs Adapter
| Pattern | Purpose | When |
|---|---|---|
| Bridge | Decouple abstraction from implementation during design | You control both sides |
| Adapter | Make incompatible interfaces work after design | Integrating 3rd-party code |
Cheat Sheet
| Feature | Details |
|---|---|
| Category | Structural |
| Problem Solved | Class explosion from multiple dimensions of variation |
| Key implementation | Composition over inheritance (has-a not is-a) |
| Pros | Scalability (add dimensions independently), Open/Closed Principle |
| Cons | Complexity (more classes initially) |
Tips to Remember 🧠
- “Remote + TV”: Remote is abstraction, TV is implementation. They vary independently.
- “Prefer composition”: This is the ultimate example of “composition over inheritance.”
- “2D to 1D”: Turns a 2D matrix of classes (M×N) into 1D (M+N).
Advertisement
Moshiour Rahman
Software Architect & AI Engineer
Enterprise software architect with deep expertise in financial systems, distributed architecture, and AI-powered applications. Building large-scale systems at Fortune 500 companies. Specializing in LLM orchestration, multi-agent systems, and cloud-native solutions. I share battle-tested patterns from real enterprise projects.
Related Articles
The Decorator Design Pattern: Dynamic Superpowers
Master the Decorator Pattern in Java. Learn how to add features to objects dynamically without inheritance explosions. The ultimate 'Wrapper' pattern.
JavaThe Visitor Design Pattern: Add Operations Without Modifying Classes
Master the Visitor Pattern in Java. Learn how to add new operations to object structures using double dispatch.
JavaThe Observer Design Pattern: Don't Call Us, We'll Call You
Master the Observer Pattern in Java. Learn how to implement event-driven architectures and decouple data sources from listeners.
Comments
Comments are powered by GitHub Discussions.
Configure Giscus at giscus.app to enable comments.