Bridge pattern

From Free net encyclopedia

Revision as of 23:30, 16 March 2006; view current revision
←Older revision | Newer revision→

The bridge pattern is a design pattern used in software engineering.

The bridge design pattern is meant to "decouple an abstraction from its implementation so that the two can vary independently" (Gamma et. al.). The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes.

When a class varies often, the features of object-oriented programming become very useful because changes to a program's code can be made easily with minimal prior knowledge about the program. The bridge pattern is useful when not only the class itself varies often but also what the class does. The class itself can be thought of as the abstraction and what the class can do as the implementation.

When the abstraction and implementation are separated they can vary independently. A good example use of the bridge design pattern comes from Design Patterns Explained: A New Perspective on Object-Oriented Design by Shalloway and Trott. Say you have an abstraction, shapes. You want to have many types of shapes and each with its own properties but there are things that all shapes do. One thing you want all shapes to do is draw themselves. However, drawing graphics to a screen can sometimes be dependent on different graphics implementations or operating systems. You want your shapes to be able to be drawn on many types of systems but having the shape itself implement them all or modifying the shape class to work with different architectures is not practical. The bridge helps by allowing you to create new classes that provide the drawing implementation. The abstraction, shape, class provides methods for getting the size or properties of a shape while the implementation, drawing, class provides an interface for drawing graphics. Now if a new shape needs to be created or you want to draw your shapes on a new graphics API then it is very easy to add a new class that implements the features you need.

Structure

Image:Bridge classdia.png

  • Client
    • The Object using the bridge pattern
  • Abstraction
    • defines the abstract interface
    • maintains the implementor reference
  • Refined Abstraction
    • Extends the interface defined by Abstraction
  • Implementor
    • defines the interface for implementation classes. (Typically the Abstraction interface defines higher level operations based on this interface operations.)
  • ConcreteImplementor
    • implements the Implementor interface

Examples

Java

The following Java program illustrates the 'shape' example given above and will output:

API1.circle at 1.000000:2.000000 radius 7.500000
API2.circle at 5.000000:7.000000 radius 27.500000
import java.util.*;

/** "Implementor" */
interface DrawingAPI {
   public void drawCircle(double x, double y, double radius);
}

/** "ConcreteImplementor" 1/2 */
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 */
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); }
}

/** "Abstraction" */
interface Shape {
   public void draw();                             // low-level
   public void resizeByPercentage(double pct);     // high-level
}

/** "Refined Abstraction" */
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;
   }
   public void draw() { drawingAPI.drawCircle(x, y, radius); }     // low-level i.e. Implementation specific
   public void resizeByPercentage(double pct) { radius *= pct; }   // high-level i.e. Abstraction specific
}

/** "Client" */
class BridgePattern {
   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();
       }
   }
}de:Brücke (Entwurfsmuster)

es:Bridge (patrón de diseño) pt:Bridge (padrão) vi:Bridge pattern