Bridge
Decouple an abstraction from its implementation so that the two can vary independently.
Intent
Split a class that has two orthogonal dimensions of variation into separate hierarchies -- an abstraction and an implementation -- connected by a bridge (composition), so that either side can evolve without affecting the other.
Problem
You have a concept that can vary along two independent axes. For example, shapes and rendering backends, or notifications and delivery channels. Using inheritance alone leads to a combinatorial explosion of subclasses (CircleSvgRenderer, CircleCanvasRenderer, SquareSvgRenderer, ...) and makes adding a new variant on either axis disproportionately expensive.
Solution
Extract one of the dimensions into a separate interface hierarchy (the implementation). The original hierarchy (the abstraction) holds a reference to an implementation object and delegates the platform-specific work to it. Both hierarchies can be extended independently, and new combinations are formed through composition rather than subclassing.
Participants
- Abstraction -- defines the high-level control interface; holds a reference to an Implementor
- RefinedAbstraction -- extends the Abstraction with richer behavior
- Implementor -- declares the interface for implementation-specific operations
- ConcreteImplementor -- provides a concrete implementation of the Implementor interface
Advantages
- Avoids the combinatorial explosion of subclasses from two orthogonal dimensions
- Abstraction and implementation can be extended independently
- Implementation details can be switched or replaced at runtime
- Follows the Open/Closed Principle -- new abstractions and implementations do not require modifying existing code
Disadvantages
- Increases complexity by adding extra levels of indirection
- Requires careful up-front analysis to identify the correct dimensions of variation
- Overkill if there is only one implementation or the abstraction never changes
Real-World Analogy
A universal TV remote (abstraction) works with any brand of television (implementation). The remote defines buttons like power, volume, and channel, while each TV brand implements how those commands are executed internally. You can buy a new remote or a new TV independently -- they communicate through a standard infrared protocol (the bridge).
Use Cases
- Shapes that can be rendered with different graphics backends (SVG, Canvas, OpenGL)
- Notifications that can be delivered through different channels (email, SMS, push)
- Device remotes that abstract over multiple device types (TV, radio, smart speaker)
- Persistence layers where business objects bridge to different storage backends (SQL, NoSQL, file)
- Cross-platform UI frameworks where widgets bridge to platform-native rendering
Code Examples
Separates Shape (abstraction) from Renderer (implementation) so new shapes and new rendering backends can be added independently.
Related Patterns
Adapter
Convert the interface of a class into another interface clients expect, enabling classes to work together that otherwise could not due to incompatible interfaces.