The Bridge pattern is a structural design pattern that separates an abstraction from its implementation so that both can be modified independently. It is used when an abstraction has multiple implementations and the client should be able to switch from one implementation to another without changing the code. The Bridge pattern consists of two main parts: Abstraction and Implementation. Abstraction defines the interface that the client uses and Implementation provides the actual implementation that Abstraction delegates its requests to.
Here’s an example to illustrate the Bridge pattern:
Suppose we need to design a drawing tool that can draw different shapes such as circles, squares, and triangles. We’ll use the Bridge pattern to separate the abstraction (the drawing tool) from its implementation (the different shapes).
First, we define the Abstraction, which is the drawing tool interface that the client uses:
public interface DrawingTool {
void drawShape();
}
Next, we define the Implementation, which is the different shapes that the drawing tool can draw:
public interface Shape {
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Circle");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Drawing Square");
}
}
public class Triangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Triangle");
}
}
Now, we create a concrete Abstraction class that uses the Implementation:
public class ConcreteDrawingTool implements DrawingTool {
private final Shape shape;
public ConcreteDrawingTool(Shape shape) {
this.shape = shape;
}
@Override
public void drawShape() {
shape.draw();
}
}
Finally, we create a client that uses the drawing tool to draw different shapes:
public class Client {
public static void main(String[] args) {
DrawingTool circleDrawingTool = new ConcreteDrawingTool(new Circle());
DrawingTool squareDrawingTool = new ConcreteDrawingTool(new Square());
DrawingTool triangleDrawingTool = new ConcreteDrawingTool(new Triangle());
circleDrawingTool.drawShape();
squareDrawingTool.drawShape();
triangleDrawingTool.drawShape();
}
}
In the example above, we used the Bridge pattern to separate the abstraction (DrawingTool) from its implementation (Shape). The client (Client) only interacts with the abstraction and can switch between different implementations (shapes) without changing any code.