design·lab

Structural pattern

Bridge

Decouple an abstraction (what) from its implementation (how) so the two can vary independently instead of multiplying into one class per combination.

✗ The problem

Inheritance ties two dimensions together

A shape and a renderer both vary — but subclassing forces one class per combination: VectorCircle, RasterCircle, VectorSquare, RasterSquare… every new shape or renderer multiplies the class count.

VectorCircle
RasterCircle
VectorSquare
RasterSquare
Class explosion: N shapes × M renderers = N×M classes. Add a triangle → 2 more classes. Add an SVG renderer → 3 more classes. The two dimensions are tangled together.
✓ The pattern

Split into two hierarchies, joined by a bridge

A Shape has-a Renderer — composition instead of inheritance. Each side grows on its own.

class Shape {
  constructor(renderer) {
    this.renderer = renderer;   // the bridge
  }
}

class Circle extends Shape {
  draw() {
    return this.renderer.drawCircle();
  }
}

// renderers implement the "how"
class VectorRenderer {
  drawCircle() { return 'vector circle'; }
}
Shape
Circle / Square
⟷ bridge
Renderer
Vector / Raster
✓ See it live

Pick a shape and a renderer — independently

Each axis changes on its own; combining them needs no new class.

Shape
Renderer
Circle drawn as vector
Bridge: 2 + 2 = 4 classes Inheritance would need: 2 × 2 = 4 classes

Add one more shape or renderer and watch the gap widen.

✓ Takeaway

Two hierarchies, one bridge

  • Decouples an abstraction from its implementation so each varies independently.
  • Prevents combinatorial explosion: N+M classes instead of N×M.
  • Differs from Adapter: Adapter retrofits existing incompatible code after the fact; Bridge is designed up front, before the hierarchies grow.
  • You already use it: JDBC drivers, cross-platform GUI toolkits, device-independent rendering backends.
🎯 Principle applied: Bridge is "favor composition over inheritance" in action — plus Open/Closed (add a shape or a renderer without touching the other) and SRP (abstraction vs rendering are separate concerns).