For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt, and this page is available as Markdown at https://nhanbe.id.vn/design-patterns/structural/bridge.md.

Decouple an abstraction from its implementation so both can vary independently. You need to support multiple implementations across multiple

Bridge

Overview

Decouple an abstraction from its implementation so both can vary independently.

When to use

  • You need to support multiple implementations across multiple abstractions.
  • You want to avoid a class explosion from combinations.

Java example

interface Renderer {
    String render(String title);
}

class HtmlRenderer implements Renderer {
    public String render(String title) { return "<h1>" + title + "</h1>"; }
}

abstract class Page {
    protected final Renderer renderer;
    protected Page(Renderer renderer) { this.renderer = renderer; }
    abstract String view();
}

class ArticlePage extends Page {
    private final String title;
    ArticlePage(Renderer renderer, String title) {
        super(renderer);
        this.title = title;
    }
    String view() { return renderer.render(title); }
}

TypeScript example

interface Renderer {
  render(title: string): string;
}

class HtmlRenderer implements Renderer {
  render(title: string): string {
    return `<h1>${title}</h1>`;
  }
}

abstract class Page {
  constructor(protected renderer: Renderer) {}
  abstract view(): string;
}

class ArticlePage extends Page {
  constructor(renderer: Renderer, private title: string) {
    super(renderer);
  }
  view(): string {
    return this.renderer.render(this.title);
  }
}

Pros and cons

Pros:

  • Avoids combinatorial subclasses.
  • Implementations are swappable.

Cons:

  • More indirection.
  • Harder to trace behavior.

Common pitfalls

  • Using Bridge when simple inheritance would do.
  • Creating too many tiny abstractions.