Bridge Pattern
Definition
Decouple an abstraction or interface from its implementation so that the two can vary independently. Bridge makes a clear-cut between abstraction and implementation.Where to use
•When you want to separate the abstract structure and its concrete implementation.•When you want to share an implementation among multiple objects,
•When you want to reuse existing resources in an 'easy to extend' fashion.
•When you want to hide implementation details from clients. Changes in implementation should have no impact on clients.
Benefits
Implementation can be selected or switched at run-time. The abstraction and implementation can be independently extended or composed.Drawbacks/consequences
Double indirection - In the example, methods are implemented by subclasses of DrawingAPI class. Shape class must delegate the message to a DrawingAPI subclass which implements the appropriate method. This will have a slight impact on performance.Bridge Pattern Class Diagram
In the class-diagram above:
•Abstraction defines the abstract interface and maintains the Implementor reference.
•Refined Abstraction extends the interface defined by Abstraction.
•Implementor defines the interface for implementation classes.
•ConcreteImplementor implements the Implementor interface.
Bridge Pattern example
public class BridgeExample { public static void main(String[] args) { Shape[] shapes = new Shape[2]; shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1()); shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2()); for (Shape shape : shapes) { shape.resizeByPercentage(2.5); shape.draw(); } } } /** "Abstraction" */ public interface Shape { public void draw(); public void resizeByPercentage(double pct); } /** "Refined Abstraction" */ public class CircleShape implements Shape { private double x, y, radius; private DrawingAPI drawingAPI; public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) { this.x = x; this.y = y; this.radius = radius; this.drawingAPI = drawingAPI; } // Implementation specific public void draw() { drawingAPI.drawCircle(x, y, radius); } // Abstraction specific public void resizeByPercentage(double pct) { radius *= pct; } } /** "Implementor" */ public interface DrawingAPI { public void drawCircle(double x, double y, double radius); } /** "ConcreteImplementor" 1/2 */ public class DrawingAPI1 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius); } } /** "ConcreteImplementor" 2/2 */ public class DrawingAPI2 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius); } }When BridgeExample is executed the result is:
c:>API1.circle at 1,000000:2,000000 radius 7,5000000
c:>API2.circle at 5,000000:7,000000 radius 27,5000000
0 comments:
Post a Comment