Bridge
- Abstract Factory
- Builder
- Prototype
- Bridge
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;