Catalog / Structural Patterns / Bridge Pattern
STRUCTURAL

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.

👥 Real-World Human Analogies & Social Roles
2 Intuitive Scenarios
Remote Control and Electronics Consumer Hardware

"A physical remote control (abstraction) and an appliance (implementation, e.g. TV, soundbar) vary independently without requiring 20 class combinations."

Universal Power Switch & Circuits Electrical Engineering

"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

Abstraction
Defines the high-level control logic and maintains reference to Implementor
Refined Abstraction
Provides variants of control logic
Implementor
Declares the interface common to all concrete platform implementations
Concrete Implementors
Platform-specific code

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm 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