xxxxxxxxxx
The bridge pattern is a type of structural design pattern that lets to split large class or closely related classes into 2 hierarchies - abstraction and implementation.
These hierarchies are independent of each other and are used whenever we need to decouple an abstraction from implementation.
This is called a Bridge pattern because it acts as a bridge between the abstract class and the implementation class.
In this pattern, the abstract classes and the implementation classes can be altered or modified independently without affecting the other one.
The above image is the UML representation of the Bridge Pattern.
There are 4 main elements of Bridge Pattern.
They are:
Abstraction – This is the core of the pattern and it defines its crux.
This contains a reference to the implementer.
Refined Abstraction – This extends the abstraction and takes refined details of the requirements and hides it from the implementors.
Implementer – This is the interface for the implementation classes.
Concrete Implementation – These are the concrete implementation classes that implement the Implementer interface.
xxxxxxxxxx
// Example
class Shape {
constructor(color) {
this.color = color;
}
draw() {}
}
// Concrete Abstractions
class Circle extends Shape {
draw() {
console.log(`Drawing a ${this.color} circle`);
}
}
class Square extends Shape {
draw() {
console.log(`Drawing a ${this.color} square`);
}
}
// Implementor
class Color {
getColor() {}
}
// Concrete Implementors
class RedColor extends Color {
getColor() {
return "red";
}
}
class BlueColor extends Color {
getColor() {
return "blue";
}
}
// Usage
const redCircle = new Circle(new RedColor());
redCircle.draw(); // Output: "Drawing a red circle"
const blueSquare = new Square(new BlueColor());
blueSquare.draw(); // Output: "Drawing a blue square"
xxxxxxxxxx
2. Bridge:
The Bridge pattern separates an object’s abstraction from its implementation, allowing them to vary independently.
Example in ReactJS:
Imagine you have a UI component library with different themes (light and dark) and different button types (primary and secondary).
// Implementations
const LightTheme = ({ children }) => (
<div className="light-theme">
{children}
</div>
);
const DarkTheme = ({ children }) => (
<div className="dark-theme">
{children}
</div>
);
const PrimaryButton = ({ onClick, label }) => (
<button className="primary-button" onClick={onClick}>
{label}
</button>
);
const SecondaryButton = ({ onClick, label }) => (
<button className="secondary-button" onClick={onClick}>
{label}
</button>
);
// Abstraction
const ThemedButton = ({ theme, onClick, label }) => (
<div className={`theme-button ${theme}`}>
<button onClick={onClick}>
{label}
</button>
</div>
);
// Usage
const App = () => (
<div>
<ThemedButton theme="light" onClick={() => alert("Light Theme")} label="Light Button" />
<ThemedButton theme="dark" onClick={() => alert("Dark Theme")} label="Dark Button" />
</div>
);