bridge
Decouple an abstraction from its implementation so both can vary independently.
SKILL.mdskills/code-quality/bridge/SKILL.md
GitHubBridge
Splits a large class (or set of closely related classes) into two separate hierarchies — abstraction and implementation — that can be developed independently.
When to Use
- A class has multiple orthogonal dimensions that need to vary independently (e.g., Shape × Renderer)
- You want to avoid a "class explosion" from combining two dimensions via inheritance
- You want to switch implementations at runtime
- Both the abstraction and its implementation should be extensible via subclassing
How to Apply
- Identify the two orthogonal dimensions
- Define an
Implementorinterface for one dimension - Create concrete
Implementorclasses - Create an
Abstractionclass that holds a reference to anImplementor - Optionally extend
Abstractionfor the other dimension's variations
Example
// Implementor dimension: rendering device
interface Renderer { renderCircle(radius: number): void; }
class VectorRenderer implements Renderer { renderCircle(r: number) { console.log(`Vector circle r=${r}`); } }
class RasterRenderer implements Renderer { renderCircle(r: number) { console.log(`Raster circle r=${r}`); } }
// Abstraction dimension: shape
abstract class Shape {
constructor(protected renderer: Renderer) {}
abstract draw(): void;
}
class Circle extends Shape {
constructor(renderer: Renderer, private radius: number) { super(renderer); }
draw() { this.renderer.renderCircle(this.radius); }
}
// Runtime: swap renderer without changing shapes
new Circle(new VectorRenderer(), 5).draw();
new Circle(new RasterRenderer(), 5).draw();