Design Patterns#7 Bridge Pattern

Burak KOCAK
2 min readMay 2, 2024

--

Design Patterns

The Bridge Pattern is a structural design pattern that decouples an abstraction from its implementation so that the two can vary independently. This pattern is useful when you want to avoid a permanent binding between an abstraction and its implementation, allowing them to vary independently.

Here’s a simple example to illustrate the Bridge Pattern:

Shape Interface: This interface represents the abstraction for different shapes. It declares a method draw() which concrete implementations will override to draw specific shapes.

// Abstraction
interface Shape {
void draw();
}

Concrete Implementors: These are concrete implementations of the Shape interface. In this example, we have Circle and Square classes implementing the Shape interface and providing their own implementation of the draw() method.

// Concrete Implementor
class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing Circle");
}
}

// Concrete Implementor
class Square implements Shape {
@Override
public void draw() {
System.out.println("Drawing Square");
}
}

Abstraction: This is an abstract class that acts as a bridge between the client code and the implementations. It holds a reference to a Shape object and provides methods to manipulate it.

// Abstraction
abstract class Drawing {
protected Shape shape;

public Drawing(Shape shape) {
this.shape = shape;
}

abstract void drawShape();
}

Refined Abstractions: These are concrete subclasses of the Drawing class. They provide specific ways of drawing shapes by implementing the drawShape() method.

// Refined Abstraction
class SimpleDrawing extends Drawing {
public SimpleDrawing(Shape shape) {
super(shape);
}

@Override
void drawShape() {
System.out.println("Simple Drawing:");
shape.draw();
}
}

// Refined Abstraction
class DetailedDrawing extends Drawing {
public DetailedDrawing(Shape shape) {
super(shape);
}

@Override
void drawShape() {
System.out.println("Detailed Drawing:");
shape.draw();
}
}

Client Code: In the main method, we create instances of shapes (Circle and Square) and drawings (SimpleDrawing and DetailedDrawing). We then call the drawShape() method on each drawing to see the output.

public class Main {
public static void main(String[] args) {
Shape circle = new Circle();
Shape square = new Square();

Drawing simpleCircleDrawing = new SimpleDrawing(circle);
Drawing simpleSquareDrawing = new SimpleDrawing(square);

Drawing detailedCircleDrawing = new DetailedDrawing(circle);
Drawing detailedSquareDrawing = new DetailedDrawing(square);

simpleCircleDrawing.drawShape();
simpleSquareDrawing.drawShape();

detailedCircleDrawing.drawShape();
detailedSquareDrawing.drawShape();
}
}

In this example:

  • Shape is the interface representing the shape objects.
  • Circle and Square are concrete implementations of the Shape interface.
  • Drawing is the abstraction that uses a Shape object internally.
  • SimpleDrawing and DetailedDrawing are refined abstractions that provide different ways of drawing shapes.

This example demonstrates the Bridge Pattern by separating the abstraction (Drawing) from its implementation (Shape). It allows for different types of drawings (SimpleDrawing and DetailedDrawing) to use different implementations of shapes (Circle and Square) without tightly coupling them together.

Prev: Design Patterns#6 Adapter Pattern

Next: -

--

--