Day 8: Bridge Pattern — Building Bridges Between Abstraction and Implementation

Sourabh Kumar
3 min readJul 24, 2024

--

Welcome to day eight of our 30-Day Design Pattern Challenge! Today, we’ll explore the Bridge Pattern, a structural design pattern that decouples abstraction from implementation.

What is it?

The Bridge Pattern separates the what (abstraction) from the how (implementation). It allows you to change the implementation of a functionality without affecting the code that uses it. This promotes flexibility and loose coupling in your codebase.

Problem

Imagine you’re building a drawing application that supports various shapes (circles, squares, etc.) and rendering them in different colors (red, green, etc.). If you directly embed color functionality within the shape classes, it becomes difficult to add new colors or change the coloring logic.

Solution

The Bridge Pattern suggests creating separate hierarchies for abstraction (shapes) and implementation (colors). An abstract Shape class defines the drawing functionality, while concrete Shape subclasses (Circle, Square) implement the specific ways to draw those shapes. Similarly, an abstract Color interface defines how to apply color, while concrete Color subclasses (Red, Green) implement the color application logic.

A bridge class, let’s call it Renderer, connects a Shape instance with a Color instance. This allows you to independently change the shape or color used for rendering without modifying the drawing code itself.

Class Diagram

The class diagram involves these entities:

  • Abstraction (Shape interface) — defines the drawing operation
  • Implementation (Color interface) — defines the color application operation
  • Concrete Abstractions (Circle, Square) — implement specific shapes
  • Concrete Implementations (Red, Green) — implement specific color applications
  • Bridge (Renderer) — connects shapes and colors for rendering
Class Diagram

Example

public interface Shape {
void draw(Renderer renderer);
}

public interface Renderer {
void render(String color);
}

public class Circle implements Shape {
@Override
public void draw(Renderer renderer) {
renderer.render("Circle");
}
}

public class Red implements Renderer {
@Override
public void render(String shape) {
System.out.println("Drawing " + shape + " in red");
}
}

public class Main {
public static void main(String[] args) {
Shape circle = new Circle();
Renderer redRenderer = new Red();
circle.draw(redRenderer); // Output: Drawing Circle in red
}
}

Benefits

  • Promotes loose coupling: Changes in implementation don’t affect the abstraction layer.
  • Improves flexibility: Easily add new shapes or colors without modifying existing code.
  • Enhances maintainability: Easier to test and modify independent components.

Disadvantages

  • Can introduce additional complexity for simple scenarios.
  • Might require creating multiple abstraction and implementation classes.

When to Use

  • When you need to decouple the what from the how in your code.
  • When you anticipate changes in implementation details.
  • When you want to support multiple variations of an abstraction or implementation.

When Not to Use

  • When dealing with a limited set of implementations and abstractions.
  • When the overhead of the Bridge Pattern outweighs the benefits.

Conclusion

The Bridge Pattern provides a powerful way to separate concerns and achieve flexibility in your code. By decoupling abstraction from implementation, you can make your code more adaptable and maintainable in the long run.

Join us tomorrow for Day 9, where we’ll delve into the Composite Pattern!

Feel free to leave comments or questions below. If you enjoyed this blog, consider giving it a clap👏!

--

--

Sourabh Kumar
Sourabh Kumar

Written by Sourabh Kumar

Software Developer. Tech Enthusiast. Innovative Solver.

No responses yet