Thursday, July 7, 2022

Structural Design Patterns # Bridge

Bridge is a structural design pattern that lets you split a large class or a set of closely related classes into two separate hierarchies—abstraction and implementation—which can be developed independently of each other.


Abstraction? Implementation? Sound scary? Stay calm and let’s consider a simple example.

Say you have a geometric Shape class with a pair of subclasses: Circle and Square. You want to extend this class hierarchy to incorporate colors, so you plan to create Red and Blue shape subclasses. However, since you already have two subclasses, you’ll need to create four class combinations such as BlueCircle and RedSquare.

Adding new shape types and colors to the hierarchy will grow it exponentially. For example, to add a triangle shape you’d need to introduce two subclasses, one for each color. And after that, adding a new color would require creating three subclasses, one for each shape type. The further we go, the worse it becomes.


This problem occurs because we’re trying to extend the shape classes in two independent dimensions: by form and by color. That’s a very common issue with class inheritance.

The Bridge pattern attempts to solve this problem by switching from inheritance to the object composition. What this means is that you extract one of the dimensions into a separate class hierarchy, so that the original classes will reference an object of the new hierarchy, instead of having all of its state and behaviors within one class.

Following this approach, we can extract the color-related code into its own class with two subclasses: Red and Blue

The Shape class then gets a reference field pointing to one of the color objects. Now the shape can delegate any color-related work to the linked color object. 

That reference will act as a bridge between the Shape and Color classes. From now on, adding new colors won’t require changing the shape hierarchy, and vice versa.


Pros and Cons

Bridge Design Pattern  Example

If we look into bridge design pattern with example, it will be easy to understand. Lets say we have an interface hierarchy in both interfaces and implementations like below image.

public interface Color { public void applyColor(); }

public abstract class Shape { //Composition - implementor protected Color color; //constructor with implementor as input argument public Shape(Color c){ this.color=c; } abstract public void applyColor(); }

We have Triangle and Pentagon implementation classes as below.
public class Triangle extends Shape{ public Triangle(Color c) { super(c); } @Override public void applyColor() { System.out.print("Triangle filled with color "); color.applyColor(); } }

public class Pentagon extends Shape{ public Pentagon(Color c) { super(c); } @Override public void applyColor() { System.out.print("Pentagon filled with color "); color.applyColor(); } }

Here are the implementation classes for RedColor and GreenColor
public class RedColor implements Color{ public void applyColor(){ System.out.println("red."); } }


class GreenColor implements Color{ public void applyColor(){ System.out.println("green."); } }

Lets test our bridge pattern implementation with a test program.
public class BridgePatternTest { public static void main(String[] args) { Shape tri = new Triangle(new RedColor()); tri.applyColor(); Shape pent = new Pentagon(new GreenColor()); pent.applyColor(); } }

Output of above bridge pattern example program is:
Triangle filled with color red.Pentagon filled with color green.

You may also like

Kubernetes AWS Java Coding Question
Microservices Core Java Python
Spring Framework AI/MLSpring Boot