Bridge

Adapter Computer Science Design Patterns
Bridge
Composite

Bridge pattern examples in various languages.

Implementation in C#

C#

The following C# program illustrates the "shape" example given above and will output:

API1.circle at 1:2 radius 7.5
API2.circle at 5:7 radius 27.5
 using System;
 
 /** "Implementor" */
 interface IDrawingAPI {
    void DrawCircle(double x, double y, double radius);
 }
 
 /** "ConcreteImplementor" 1/2 */
 class DrawingAPI1 : IDrawingAPI {
    public void DrawCircle(double x, double y, double radius)
    {
        System.Console.WriteLine("API1.circle at {0}:{1} radius {2}", x, y, radius);
    }
 }
 
 /** "ConcreteImplementor" 2/2 */
 class DrawingAPI2 : IDrawingAPI
 {
    public void DrawCircle(double x, double y, double radius)
    {
        System.Console.WriteLine("API2.circle at {0}:{1} radius {2}", x, y, radius);
    }
 }
 
 /** "Abstraction" */
 interface IShape {
    void Draw();                             // low-level (i.e. Implementation-specific)
    void ResizeByPercentage(double pct);     // high-level (i.e. Abstraction-specific)
 }
 
 /** "Refined Abstraction" */
 class CircleShape : IShape {
    private double x, y, radius;
    private IDrawingAPI drawingAPI;
    public CircleShape(double x, double y, double radius, IDrawingAPI drawingAPI)
    {
        this.x = x;  this.y = y;  this.radius = radius;
        this.drawingAPI = drawingAPI;
    }
    // low-level (i.e. Implementation-specific)
    public void Draw() { drawingAPI.DrawCircle(x, y, radius); }
    // high-level (i.e. Abstraction-specific)
    public void ResizeByPercentage(double pct) { radius *= pct; }
 }
 
 /** "Client" */
 class BridgePattern {
    public static void Main(string[] args) {
        IShape[] shapes = new IShape[2];
        shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1());
        shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2());
 
        foreach (IShape shape in shapes) {
            shape.ResizeByPercentage(2.5);
            shape.Draw();
        }
    }
 }

C# using generics

The following C# program illustrates the "shape" example given above and will output:

API1.circle at 1:2 radius 7.5
API2.circle at 5:7 radius 27.5
 using System;
 
 /** "Implementor" */
 interface IDrawingAPI {
    void DrawCircle(double x, double y, double radius);
 }
 
 /** "ConcreteImplementor" 1/2 */
 struct DrawingAPI1 : IDrawingAPI {
    public void DrawCircle(double x, double y, double radius)
    {
        System.Console.WriteLine("API1.circle at {0}:{1} radius {2}", x, y, radius);
    }
 }
 
 /** "ConcreteImplementor" 2/2 */
 struct DrawingAPI2 : IDrawingAPI
 {
    public void DrawCircle(double x, double y, double radius)
    {
        System.Console.WriteLine("API2.circle at {0}:{1} radius {2}", x, y, radius);
    }
 }
 
 /** "Abstraction" */
 interface IShape {
    void Draw();                             // low-level (i.e. Implementation-specific)
    void ResizeByPercentage(double pct);     // high-level (i.e. Abstraction-specific)
 }
 
 /** "Refined Abstraction" */
 class CircleShape<T> : IShape
    where T : struct, IDrawingAPI
 {
    private double x, y, radius;
    private IDrawingAPI drawingAPI = new T();
    public CircleShape(double x, double y, double radius)
    {
        this.x = x;  this.y = y;  this.radius = radius;
    }
    // low-level (i.e. Implementation-specific)
    public void Draw() { drawingAPI.DrawCircle(x, y, radius); }
    // high-level (i.e. Abstraction-specific)
    public void ResizeByPercentage(double pct) { radius *= pct; }
 }
 
 /** "Client" */
 class BridgePattern {
    public static void Main(string[] args) {
        IShape[] shapes = new IShape[2];
        shapes[0] = new CircleShape<DrawingAPI1>(1, 2, 3);
        shapes[1] = new CircleShape<DrawingAPI2>(5, 7, 11);
 
        foreach (IShape shape in shapes) {
            shape.ResizeByPercentage(2.5);
            shape.Draw();
        }
    }
 }
Implementation in Python

The following Python program illustrates the "shape" example given above and will output:

API1.circle at 1:2 7.5
API2.circle at 5:7 27.5
# Implementor
class DrawingAPI:
        def drawCircle(x, y, radius):
                pass
 
# ConcreteImplementor 1/2
class DrawingAPI1(DrawingAPI):
        def drawCircle(self, x, y, radius):
                print "API1.circle at %f:%f radius %f" % (x, y, radius)
 
# ConcreteImplementor 2/2
class DrawingAPI2(DrawingAPI):
        def drawCircle(self, x, y, radius):
                print "API2.circle at %f:%f radius %f" % (x, y, radius)
 
# Abstraction
class Shape:
        # low-level
        def draw(self):
                pass
 
        # high-level
        def resizeByPercentage(self, pct):
                pass
 
# Refined Abstraction
class CircleShape(Shape):
        def __init__(self, x, y, radius, drawingAPI):
                self.__x = x
                self.__y = y
                self.__radius = radius
                self.__drawingAPI = drawingAPI
 
        # low-level i.e. Implementation specific
        def draw(self):
                self.__drawingAPI.drawCircle(self.__x, self.__y, self.__radius)
 
        # high-level i.e. Abstraction specific
        def resizeByPercentage(self, pct):
                self.__radius *= pct
 
def main():
        shapes = [
                CircleShape(1, 2, 3, DrawingAPI1()),
                CircleShape(5, 7, 11, DrawingAPI2())
        ]
 
        for shape in shapes:
                shape.resizeByPercentage(2.5)
                shape.draw()
 
if __name__ == "__main__":
        main()
Implementation in Ruby

An example in Ruby.

class Abstraction
  def initialize(implementor)
    @implementor = implementor
  end
 
  def operation
    raise 'Implementor object does not respond to the operation method' unless @implementor.respond_to?(:operation)
    @implementor.operation
  end
end
 
class RefinedAbstraction < Abstraction
  def operation
    puts 'Starting operation... '
    super
  end
end
 
class Implementor
  def operation
    puts 'Doing neccessary stuff'
  end
end
 
class ConcreteImplementorA < Implementor
  def operation
    super
    puts 'Doing additional stuff'
  end
end
 
class ConcreteImplementorB < Implementor
  def operation
    super
    puts 'Doing other additional stuff'
  end
end
 
normal_with_a = Abstraction.new(ConcreteImplementorA.new)
normal_with_a.operation
# Doing neccessary stuff
# Doing additional stuff
 
normal_with_b = Abstraction.new(ConcreteImplementorB.new)
normal_with_b.operation
# Doing neccessary stuff
# Doing other additional stuff
 
refined_with_a = RefinedAbstraction.new(ConcreteImplementorA.new)
refined_with_a.operation
# Starting operation...
# Doing neccessary stuff
# Doing additional stuff
 
refined_with_b = RefinedAbstraction.new(ConcreteImplementorB.new)
refined_with_b.operation
# Starting operation...
# Doing neccessary stuff
# Doing other additional stuff
Implementation in Scala

A Scala implementation of the Java drawing example with the same output.

  /** "Implementor" */
  trait DrawingAPI {
    def drawCircle(x:Double, y:Double, radius:Double)
  }
 
  /** "ConcreteImplementor" 1/2 */
  class DrawingAPI1 extends DrawingAPI {
    def drawCircle(x:Double, y:Double, radius:Double) {
      printf("API1.circle at %f:%f radius %f\n", x, y, radius)
    }
  }
 
  /** "ConcreteImplementor" 2/2 */
  class DrawingAPI2 extends DrawingAPI {
    def drawCircle(x:Double, y:Double, radius:Double) {
      printf("API2.circle at %f:%f radius %f\n", x, y, radius)
    }
  }
 
  /** "Abstraction" */
  trait Shape {
     def draw()                             // low-level
     def resizeByPercentage(pct:Double)     // high-level
  }
 
  /** "Refined Abstraction" */
  class CircleShape(var x:Double, var y:Double,
    var radius:Double, val drawingAPI:DrawingAPI) extends Shape {
 
    // low-level i.e. Implementation specific
    def draw() = drawingAPI.drawCircle(x, y, radius)
 
    // high-level i.e. Abstraction specific
    def resizeByPercentage(pct:Double) = radius *= pct
  }
 
  /** "Client" */
  val shapes = List(
    new CircleShape(1, 2, 3, new DrawingAPI1),
    new CircleShape(5, 7, 11, new DrawingAPI2)
  )
 
  shapes foreach { shape =>
    shape.resizeByPercentage(2.5)
    shape.draw()
  }
Implementation in D

An example in D.

import std.stdio;
 
/** "Implementor" */
interface DrawingAPI {
    void drawCircle(double x, double y, double radius);
}
 
/** "ConcreteImplementor" 1/2 */
class DrawingAPI1: DrawingAPI {
    void drawCircle(double x, double y, double radius) {
        writefln("\nAPI1.circle at %f:%f radius %f", x, y, radius);
    }
}
 
/** "ConcreteImplementor" 2/2 */
class DrawingAPI2: DrawingAPI {
    void drawCircle(double x, double y, double radius) {
        writefln("\nAPI2.circle at %f:%f radius %f", x, y, radius);
    }
}
 
/** "Abstraction" */
interface Shape {
    void draw(); // low-level
    void resizeByPercentage(double pct); // high-level
}
 
/** "Refined Abstraction" */
class CircleShape: Shape {
    this(double x, double y, double radius, DrawingAPI drawingAPI) {
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.drawingAPI = drawingAPI;
    }
 
    // low-level i.e. Implementation specific
    void draw() {
        drawingAPI.drawCircle(x, y, radius);
    }
    // high-level i.e. Abstraction specific
    void resizeByPercentage(double pct) {
        radius *= pct;
    }
private:
    double x, y, radius;
    DrawingAPI drawingAPI;
}
 
int main(string[] argv) {
    auto api1 = new DrawingAPI1();
    auto api2 = new DrawingAPI2();
 
    auto c1 = new CircleShape(1, 2, 3, api1);
    auto c2 = new CircleShape(5, 7, 11, api2);
 
    Shape[4] shapes;
    shapes[0] = c1;
    shapes[1] = c2;
 
    shapes[0].resizeByPercentage(2.5);
    shapes[0].draw();
    shapes[1].resizeByPercentage(2.5);
    shapes[1].draw();
 
    return 0;
}
Implementation in Perl

This example in Perl uses the MooseX::Declare module.

# Implementor
role Drawing::API {
    requires 'draw_circle';
}
 
# Concrete Implementor 1
class Drawing::API::1 with Drawing::API {
    method draw_circle(Num $x, Num $y, Num $r) {
        printf "API1.circle at %f:%f radius %f\n", $x, $y, $r;
    }
}
 
# Concrete Implementor 2
class Drawing::API::2 with Drawing::API {
    method draw_circle(Num $x, Num $y, Num $r) {
        printf "API2.circle at %f:%f radius %f\n", $x, $y, $r;
    }
}
 
# Abstraction
role Shape {
    requires qw( draw resize );
}
 
# Refined Abstraction
class Shape::Circle with Shape {
    has $_  => ( is => 'rw', isa  => 'Any' ) for qw( x y r );
    has api => ( is => 'ro', does => 'Drawing::API' );
 
    method draw() {
        $self->api->draw_circle( $self->x, $self->y, $self->r );
    }
 
    method resize(Num $percentage) {
        $self->{r} *= $percentage;
    }
}
 
my @shapes = (
    Shape::Circle->new( x=>1, y=>2, r=>3,  api => Drawing::API::1->new ),
    Shape::Circle->new( x=>5, y=>7, r=>11, api => Drawing::API::2->new ),
)
 
$_->resize( 2.5 ) and $_->draw for @shapes;


Clipboard

To do:
Add more illustrations.


Adapter Computer Science Design Patterns
Bridge
Composite


You have questions about this page?
Ask it here:


Create a new page on this book:

Last modified on 21 May 2013, at 19:56