THN Interview Prep

Bridge (Structural)

Intent / problem it solves

Decouple abstraction (what clients use) from implementation (how it works) so they can vary independently. Avoids an explosion of subclasses for every combination.

When to use / when NOT

Use when both dimensions (e.g. UI vs OS, renderer vs shape) change often and inheritance would multiply classes.

Avoid when a single implementation exists or when Strategy already covers the variation cleanly with less structure.

Structure

Abstraction holds a reference to implementor; refined abstractions call through it.

Loading diagram…

Go example

package main

import "fmt"

type Drawer interface {
	Fill(text string) string
}

type AsciiDrawer struct{}

func (AsciiDrawer) Fill(text string) string { return "[" + text + "]" }

type Banner struct {
	drawer Drawer
}

func (banner Banner) Show(title string) string {
	return banner.drawer.Fill(title)
}

func main() {
	banner := Banner{drawer: AsciiDrawer{}}
	fmt.Println(banner.Show("sale"))
}

JavaScript example

class RemoteRenderer {
  paint(shapeName) {
    throw new Error('override');
  }
}

class SvgRenderer extends RemoteRenderer {
  paint(shapeName) {
    return `<shape name="${shapeName}" />`;
  }
}

class CanvasRenderer extends RemoteRenderer {
  paint(shapeName) {
    return { engine: 'canvas', shapeName };
  }
}

class ShapeAbstraction {
  constructor(name, renderer) {
    this.name = name;
    this.renderer = renderer;
  }

  draw() {
    return this.renderer.paint(this.name);
  }
}

const picture = new ShapeAbstraction('triangle', new SvgRenderer());
console.log(picture.draw());

Interview phrase

“Bridge separates the thing users interact with from the engine underneath so I can add a new renderer without subclassing every shape.”

Document alongside LLD for multi-backend features (file storage, notifications) in LLD case studies.

Mark this page when you finish learning it.

Last updated on

Spotted something unclear or wrong on this page?

On this page