Bridge Pattern
Decouple an abstraction from its implementation so that the two can vary independently.
Intent & Objective
Split a large class or a set of closely related classes into two separate hierarchies—abstraction and implementation—which can be developed independently of each other.
"A physical remote control (abstraction) and an appliance (implementation, e.g. TV, soundbar) vary independently without requiring 20 class combinations."
"A standardized wall switch (abstraction) controls LED, incandescent, or halogen circuits (implementation) without changing the mechanical toggle."
The Problem
Cartesian product class explosion: if you have 2 GUI shapes (Circle, Square) and 2 rendering backends (OpenGL, DirectX), subclassing produces 4 classes. Add 3 more shapes and 2 more platforms and you get (5 \times 4 = 20) classes.
The Solution
Separate into Abstraction (`Shape`) and Implementation (`Renderer`). The Abstraction holds a reference to an Implementation object and delegates low-level work.
Key Participants & Architectural Roles
Code Samples (Traditional OOP vs Functional Programming)
Available in C++, Python, and JavaParadigm Contrast: Traditional OOP vs Functional / Data-Oriented
In OOP, Bridge uses two separate class hierarchies connected by object composition. In Functional Programming, Bridge is naturally achieved by passing rendering/implementation functions directly into higher-order functions.
Advantages
- âś“ Avoids Cartesian product class explosions ((M + N) classes instead of (M \times N))
- âś“ Follows Single Responsibility and Open/Closed principles
- âś“ Hides implementation details completely from client code
Trade-offs
- âś— Increases overall design complexity for simple systems
When to Apply
- → When you want to divide a monolithic class that has multiple variants of some functionality (e.g. cross-platform GUI engines or database adapters)
When to Avoid
- ! When an abstraction will only ever have one fixed implementation