Gang of Four Structural pattern: Bridge
Structural Pattern
Separates an object’s interface from its implementation. Decouple an abstraction from its implementation so that the two can vary independently.
This pattern is pretty similar to the Adapter pattern. Notice some differences though:
Adapter is more about wrapping a third party API so it can be used by the application API.
Bridge is more about having the ability to slot in different implementation.
The Bridge has an abstract class that wraps the implementation which is itself extended to add extra functionality (e.g. ShapeBridgeImpl.drawShape())
The Bridge pattern in this example can be considered to be a combination of the Strategy and Template patterns
To get the code for this example:
git clone https://github.com/spotadev/gangoffour.git
In src/main/java navigate to this package:
com.javaspeak.designpatterns.go4.structural.bridge
You can run the code from the main method of:
BridgeApplication
This example has an abstract class called AbstractShapeBridge which wraps ShapeBuilder so that calling the buildShape() method of AbstractShapeBridge internally calls the buildShape() method of the ShapeBuilder.
This wrapping allows the implementation of ShapeBuilder, currently TriangleBuilder, to be readily switched for another implementation such as SquareBuilder.
The implementation of the ShapeBuilder is passed through the constructor of AbstractBridge.
BridgeImpl extends AbstractBridge and adds its own method, drawShape() to draw the shape. Internally the drawShape() method makes a call to the buildShape() method in AbstractShapeBridge.
package com.javaspeak.designpatterns.go4.structural.bridge;
/**
* Text book description:
* <ul>
* Bridge: Separates an object’s interface from its implementation. Decouple an abstraction
* from its implementation so that the two can vary independently.
* </ul>
* This application has an abstract class called AbstractShapeBridge which wraps ShapeBuilder so
* that calling the buildShape() method of AbstractShapeBridge internally calls the buildShape()
* method of the ShapeBuilder.
* <p>
* This wrapping allows the implementation of ShapeBuilder, currently TriangleBuilder, to be
* readily switched for another implementation such as SquareBuilder.
* <p>
* The implementation of the ShapeBuilder is passed through the constructor of AbstractBridge.
* <p>
* BridgeImpl extends AbstractBridge and adds its own method, drawShape() to draw the shape.
* Internally the drawShape() method makes a call to the buildShape() method in AbstractShapeBridge.
* <p>
* This pattern is pretty similar to the Adapter pattern. Notice some differences though:
* <ul>
* <li>
* Adapter is more about wrapping a third party API so it can be used by the application
* API.
* </li>
* <li>
* Bridge is more about having the ability to slot in different implementation.
* </li>
* <li>
* The Bridge has an abstract class that wraps the implementation which is itself extended
* to add extra functionality (e.g. ShapeBridgeImpl.drawShape())
* </li>
* <li>
* The Bridge pattern in this example can be considered to be a combination of the
* Strategy and Template patterns
* </li>
* </ul>
* @author John Dickerson - 22 Feb 2020
*/
public class BridgeApplication {
/**
* Calls drawShape() on the bridge implementation
*/
public void drawShape() {
ShapeBridgeImpl shapeBridge = new ShapeBridgeImpl();
shapeBridge.drawShape();
}
/**
* @param args
*/
public static void main( String[] args ) {
BridgeApplication application = new BridgeApplication();
application.drawShape();
}
}
package com.javaspeak.designpatterns.go4.structural.bridge;
/**
* This abstract bridge class wraps the ShapeBuilder. Calling buildShape() on AbstractShapeBridge
* internally calls the buildShape() method of the underlying ShapeBuilder.
* <p>
* The idea with the bridge is that the implementation for the underlying ShapeBuilder can be
* switched. This example is using a TriangleBuilder but the TriangleBuilder could be swapped for
* another shape builder.
*
* @author John Dickerson - 24 Feb 2020
*/
public abstract class AbstractShapeBridge {
protected ShapeBuilder shapeBuilder;
/**
* Constructor
*
* The constructor allows the implementation for the ShapeBuilder to be passed in.
*
* @param shapeBuilder
*/
public AbstractShapeBridge( ShapeBuilder shapeBuilder ) {
this.shapeBuilder = shapeBuilder;
}
/**
* Defines the API for building a shape. Internally calls the shapeBuilder to build the shape.
* Notice that the implementation for the shapeBuilder is pluggable.
*
* @return shape
*/
public Shape buildShape() {
return shapeBuilder.buildShape();
}
}
package com.javaspeak.designpatterns.go4.structural.bridge;
/**
* Interface used for Shape.
* <p>
* The interface is used both by ShapeBuilder implementations and the AbstractShapeBridge.
*
* @author John Dickerson - 24 Feb 2020
*/
public interface Shape {
/**
* draws shape
*/
public void draw();
}
package com.javaspeak.designpatterns.go4.structural.bridge;
/**
* This class extends the AbstractShapeBridge and adds functionality.
* <p>
* The added functionality is a drawShape() method
*
* @author John Dickerson - 24 Feb 2020
*/
public class ShapeBridgeImpl extends AbstractShapeBridge {
/**
* Constructor
*/
public ShapeBridgeImpl() {
super( new TriangleBuilder() );
}
/**
* Provides additional method which application can call.
* <p>
* Extends functionality of AbstractShapeBridge
*/
public void drawShape() {
System.out.println(
"Drawing a Shape using " + this.shapeBuilder.getClass().getName() );
this.buildShape().draw();
}
}
package com.javaspeak.designpatterns.go4.structural.bridge;
/**
* This interface is central to the Bridge pattern as it allows different implementations to be
* plugged in for the shape building.
* <p>
* For example the TriangleBuilder can be easily switched for a SquareBuilder.
*
* @author John Dickerson - 24 Feb 2020
*/
public interface ShapeBuilder {
/**
* Builds a Shape
*
* @return
* a Shape
*/
Shape buildShape();
}
package com.javaspeak.designpatterns.go4.structural.bridge;
/**
* The TriangleBuilder returns a Triangle as a Shape
*
* @author John Dickerson - 24 Feb 2020
*/
public class Triangle implements Shape {
@Override
public void draw() {
StringBuilder sb = new StringBuilder( "\n" );
sb.append( " x \n" );
sb.append( " x x \n" );
sb.append( " x x \n" );
sb.append( " x x \n" );
sb.append( "x x x x x\n" );
System.out.println( sb.toString() );
}
}
package com.javaspeak.designpatterns.go4.structural.bridge;
/**
* The TriangleBuilder is pluggable ShapeBuilder in this Bridge pattern. It can be readily switched
* for another ShapeBuilder.
* <p>
* ShapeBuilderImpl passes the TriangleBuilder to its super class, AbstractShapeBuilder via its
* constructor.
*
* @author John Dickerson - 24 Feb 2020
*/
public class TriangleBuilder implements ShapeBuilder {
@Override
public Shape buildShape() {
return new Triangle();
}
}
Back: Gang of Four
Page Author: JD