Bridge Design Pattern — An Unknowingly known pattern
Structural design patterns often solve the kinds of architectural problems we run into when systems start growing new features and…
Bridge Design Pattern — An Unknowingly known pattern
Structural design patterns often solve the kinds of architectural problems we run into when systems start growing new features and variations. The Bridge pattern is one of those elegant solutions that quietly prevents a project from turning into an inheritance jungle.
At its core, the Bridge pattern is about separating two dimensions of change — one representing the abstraction (what the client sees) and the other representing the implementation (how it actually works). When these evolve independently, the design stays clean, flexible, and free from exponential class growth.
1. What the Bridge Pattern Really Means
The official definition says:
“Decouple the abstraction from its implementation so that both can vary independently.”
But the words “abstraction” and “implementation” here often confuse people because they do not refer to Java interfaces or abstract classes. Instead:
- Abstraction = the final behavior the client interacts with
- Implementation = the underlying mechanism that the abstraction uses
The pattern simply connects these two hierarchies via composition, forming a “bridge.”
Why not just use inheritance?
Imagine you’re building a UI system with two types of views — LongView and ShortView — and two resource types such as Author and Book. Using inheritance, you’d be forced to create:
- LongViewAuthor
- LongViewBook
- ShortViewAuthor
- ShortViewBook
Four classes — and that’s only with two views and two resources. Add a new view (say, MobileView) or a new resource (Album), and the number of combinations grows multiplicatively.
This is known as class explosion, and Bridge eliminates it.
2. The Structure of the Bridge Pattern
At a high level, the Bridge pattern involves two separate hierarchies:
A. Abstraction Side
- Abstraction Contains high-level operations and a reference to the implementor.
- Refined Abstraction Subclasses that extend or specialize the abstraction.
B. Implementation Side
- Implementor (Interface) Defines the internal operations the abstraction relies on.
- Concrete Implementors Provide the actual implementation.
Visually:
Abstraction ------------------> Implementor
| |
| |
Refined Abstractions Concrete Implementors
The magic lies in the fact that the abstraction has a reference to the implementor. This link is the “bridge.”
3. When You Should Reach for the Bridge Pattern
Bridge is most helpful when:
1. You expect multiple, independent dimensions of change
Examples:
- Shape × Color
- Remote × Device
- View × Resource type
2. You want to switch implementations at runtime
For instance, drawing a shape using a new rendering engine without touching shape classes.
3. Abstractions and implementations should evolve separately
You might redesign the implementation layer entirely without breaking the public abstraction layer.
4. Practical Advantages
- Stops subclass explosion Only two parallel hierarchies — no combinatorial mess.
- Promotes clean separation of concerns Each hierarchy has its own responsibility.
- Improves flexibility and testability You can mock the implementor when testing the abstraction.
- Keeps client code clean Consumers work with the abstraction, unaware of platform-specific details.
5. Drawbacks to Keep in Mind
- More moving pieces Two hierarchies + the wiring between them.
- Tougher for newcomers It’s easier to understand “extend this class” than “compose across hierarchies.”
- Overkill for simple variations If you only have one dimension of change, Strategy or plain composition may be enough.
6. Examples For Bridge Pattern
Below are the differnt examples where we can use the Bridge Pattern
Example 1: Shapes × Colors (Classic Textbook Example)
Two things can vary independently:
- The shape (circle, square…)
- The color (red, blue…)
Instead of mixing them into dozens of shape-color subclasses, we use Bridge.
Implementor & its Implementations
interface Color { String fill(); }
class Red implements Color { public String fill() { return "red"; } }
class Blue implements Color { public String fill() { return "blue"; } }
Abstraction
abstract class Shape {
protected final Color color;
protected Shape(Color color) { this.color = color; }
abstract String draw();
}
Refined Abstractions
class Circle extends Shape {
public Circle(Color color) { super(color); }
public String draw() { return "Drawing a " + color.fill() + " circle"; }
}
class Square extends Shape {
public Square(Color color) { super(color); }
public String draw() { return "Drawing a " + color.fill() + " square"; }
}
Usage
Shape s1 = new Circle(new Red());
Shape s2 = new Square(new Blue());
Each dimension is free to grow on its own.
Example 2: ReentrantLock in Java → A Real-World Bridge
Even though it’s not a pure textbook implementation, ReentrantLock uses Bridge-like layering internally.
- Abstraction:
Lockinterface - Refined abstraction:
ReentrantLock - Implementor: low-level locking mechanism (
Sync) - Concrete implementors:
FairSync&NonfairSync - Underlying engine:
AbstractQueuedSynchronizer (AQS)
This separation allows:
- the public API to remain stable,
- while the actual locking strategy can change independently.
This is Bridge adopted to a concurrency system.
7. Bridge vs Strategy — A Quick but Important Distinction
Both patterns use composition, both delegate to another class — but they serve different purposes:
Bridge
- Two structural dimensions vary independently
- Class explosion prevention
- Shape × Color, Remote × Device, Lock API × Lock Implementation
Strategy
- One dimension: behavior varies at runtime
- Choose an algorithm dynamically (e.g., payment methods, retry policies)
If you see two hierarchies, it’s Bridge. If you see one hierarchy of alternatives, it’s Strategy.
8. A Quick Mental Model (Rule of Thumb)
If a high-level class holds a pluggable internal component and forwards operations to it, there’s a good chance you’re looking at a Bridge (sometimes combined with Template Method or Strategy).
Conclusion
The Bridge pattern shines when your code starts developing two axes of change. Instead of drowning in subclasses, Bridge lets you keep the design flat, flexible, and maintainable. The examples — from classic shapes to Java’s own locking mechanisms — show how powerful this separation can be in real-world systems.
Use it when your abstractions and implementations truly need to evolve independently. Skip it when the problem is simpler. When used appropriately, the Bridge pattern is one of those tools that significantly improves architecture without forcing itself loudly into the codebase.
메타데이터
- post_id
- f4fa46b32dc2
- slug
- bridge-design-pattern-an-unknowingly-known-pattern-f4fa46b32dc2
- url
- https://medium.com/@prassu.59/bridge-design-pattern-an-unknowingly-known-pattern-f4fa46b32dc2
- canonical_url
- https://medium.com/@prassu.59/bridge-design-pattern-an-unknowingly-known-pattern-f4fa46b32dc2
- author_url
- https://medium.com/@prassu.59
- status
- ok
- fetched_at
- 2026-08-09 21:07:04