Privacy Policy Cookie Policy Terms and Conditions Wzorzec mostu - Wikipedia, wolna encyklopedia

Wzorzec mostu

Z Wikipedii

Wzorzec mostu (ang. Bridge builder) jest strukturalnym wzorcem projektowym, który pozwala oddzielić abstrakcje obiektu od jego implementacji.

Spis treści

[edytuj] Przykłady

Wyobraźmy sobie abstrakcję którą jest figura. Można ją wyszczególnić na np. kwadraty, czy trójkąty, jednak są pewne metody dla każdej figury jak np. rysowanie. Jednak rysowanie może być różne dla różnych bibliotek graficznych czy systemów operacyjnych. Wzorzec mostu pozwala na stworzenie nowych klas które dostarczają konkretnych implementacji do rysowania. Klasa abstrakcyjna figury dostarcza informacji o figurze (np. wielkość) podczas gdy implementacja - rysowanie dostarcza interfejs do rysowania.

[edytuj] Przykłady kodu

[edytuj] Java

Wyjście:

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;
   }
   // 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) {
       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();
       }
   }
}

[edytuj] C++

Notice that a circle can be drawn by either of the following two (drawing) API's. But also a square can be drawn by both API's. The drawing API's are simulated as output to console.

#include <iostream>

using namespace std; //For brevity.
//Implementor class DrawingAPI { public: virtual void DrawCircle(const double x, const double y, const double radius) = 0; virtual void DrawSquare(const double x, const double y) = 0; };
// ConcreteImplementor 1/2 class OpenGL : public DrawingAPI { public: void DrawCircle(const double x, const double y, const double radius) { cout<<"OpenGL based circle drawn at "<<x<<":"<<y<<" radius "<<radius<<endl; } void DrawSquare(const double x, const double y) { cout<<"OpenGL based square drawn at "<<x<<":"<<y<<endl; } };
// ConcreteImplementor 2/2 class DirectX : public DrawingAPI { public: void DrawCircle(const double x, const double y, const double radius) { cout<<"DirectX based circle drawn at "<<x<<":"<<y<<" radius "<<radius<<endl; } void DrawSquare(const double x, const double y) { cout<<"DirectX based square drawn at "<<x<<":"<<y<<endl; } };
//Abstraction" class Shape { public: //Constrctor Shape(double x, double y, double radius, DrawingAPI* da) : _x(x), _y(y), _radius(radius), _da(da) { } Shape(double x, double y, DrawingAPI* da) : _x(x), _y(y), _da(da) { } public: // low-level virtual void Draw() = 0; protected: void DrawCircle() { _da->DrawCircle(_x, _y, _radius); } void DrawSquare() { _da->DrawSquare(_x, _y); } // high-level // This needs to be refined in the Refined Abstraction classes. virtual void ResizeByPercentage(double const pct) = 0; protected: double _x, _y, _radius; DrawingAPI* _da; // Shapes could be displayed by different DrawingAPI's. };
//Refined Abstraction: define a Circle. class Circle : public Shape { public : //Constructor Circle(double x, double y, double radius, DrawingAPI* da) : Shape(x, y, radius, da) { } public: //Behavior // low-level i.e. Implementation specific. // Draw doesn't even know what parameters it's using and WHO is drawing it. void Draw() { DrawCircle(); } // High-level i.e. Abstraction specific. // A circle has a radius, but a square has a length (for example). void ResizeByPercentage(const double pct) { _radius *= pct; } };
//Refined Abstraction: define a Square. class Square : public Shape { public : //Constructor Square(double x, double y, DrawingAPI* da) : Shape(x, y, da) { } public: //Behavior // Low-level i.e. Implementation specific. // Draw doesn't even know what parameters it's using and WHO is drawing it. void Draw() { DrawSquare(); } // High-level i.e. Abstraction specific. // A circle has a radius, but a square has a length (for example). void ResizeByPercentage(const double pct) { _x *= pct; } };

//The Client. // -->> int main() merely demonstrates the interchangebility. int main() { Shape* TheShape[4]; //2 shapes x 2 implementations = 4 client-options. DrawingAPI* DA[2]; //2 Implementations. DA[0] = new OpenGL; DA[1] = new DirectX;
TheShape[0] = new Circle(1, 2, 7.5, DA[0]); //Draw circle with OpenGL TheShape[0]->Draw();
TheShape[1] = new Circle(5, 7, 27.5, DA[1]); //Draw circle with DirectX TheShape[1]->Draw();
TheShape[2] = new Square(10, 14, DA[0]); //Draw square with OpenGL TheShape[2]->Draw();
TheShape[3] = new Square(2.9, 80, DA[1]); //Draw square with DirectX TheShape[3]->Draw();
//Give back allocated memory. delete DA[0], DA[1]; delete TheShape[0], TheShape[1], TheShape[2], TheShape[3];
return 0; }

[edytuj] C#

wyjście:

API1.circle at 1:2 radius 7.5
API2.circle at 5:7 radius 27.5
using System;

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

/** "ConcreteImplementor" 1/2 */
class DrawingAPI1 : DrawingAPI {
   public void DrawCircle(double x, double y, double radius) 
   {
       System.Console.WriteLine("API1.circle at {0}:{1} radius {2}\n", x, y, radius); 
   }
}

/** "ConcreteImplementor" 2/2 */
class DrawingAPI2 : DrawingAPI 
{
   public void DrawCircle(double x, double y, double radius) 
   { 
       System.Console.WriteLine("API2.circle at {0}:{1} radius {2}\n", x, y, radius); 
   }
}

/** "Abstraction" */
interface Shape {
   void Draw();                             // low-level
   void ResizeByPercentage(double pct);     // high-level
}

/** "Refined Abstraction" */
class CircleShape : 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;
   }
   // 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) {
       Shape[] shapes = new Shape[2];
       shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1());
       shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2());

       foreach (Shape shape in shapes) {
           shape.ResizeByPercentage(2.5);
           shape.Draw();
       }
   }
}

[edytuj] Perl

wyjście:

API1.circle at 1:2 radius 7.5
API2.circle at 5:7 radius 27.5
### ConcreteImplementor 1/2
package DrawingAPI1;

sub new {
        my $class = shift;
        return bless({}, $class);
}

sub draw_circle {
        my($self, $x, $y, $radius) = @_;

        print("API1.circle at $x:$y radius $radius\n");
}

1;

### ConcreteImplementor 2/2
package DrawingAPI2;

sub new {
        my $class = shift;
        return bless({}, $class);
}

sub draw_circle {
        my($self, $x, $y, $radius) = @_;

        print("API2.circle at $x:$y radius $radius\n");
}

1;

### Refined Abstraction
package CircleShape;

sub new {
        my $class = shift;
        my ($x, $y, $radius, $drawing_api) = @_;

        my $self = bless({
                x => $x,
                y => $y,
                radius => $radius,
                drawing_api => $drawing_api,
        }, $class);

        return $self;
}

sub draw {
        my $self = shift;
        $self->{drawing_api}->draw_circle(
                $self->{x}, $self->{y}, $self->{radius});
}

sub resize_by_percentage {
        my($self, $percent) = @_;
        $self->{radius} *= $percent;
}

1;

### client
my @shapes = (
        CircleShape->new(1, 2, 3,  DrawingAPI1->new),
        CircleShape->new(5, 7, 11, DrawingAPI2->new),
);

foreach my $shape (@shapes) {
        $shape->resize_by_percentage(2.5);
        $shape->draw();
}

[edytuj] PHP

#!/usr/local/bin/php
<?php
/** "Implementor" */
interface DrawingAPI {
   public function drawCircle($x, $y, $radius);
}

/** "ConcreteImplementor" 1/2 */
class DrawingAPI1 implements DrawingAPI {
   public function drawCircle($x, $y, $radius) 
   { echo "API1.circle at $x:$y radius $radius\n"; }
}

/** "ConcreteImplementor" 2/2 */
class DrawingAPI2 implements DrawingAPI {
   public function drawCircle($x, $y, $radius) 
  { echo "API2.circle at $x:$y radius $radius\n"; }
}

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

/** "Refined Abstraction" */
class CircleShape implements Shape {
   private $x;
   private $y;
   private $radius;
   private $drawingAPI;
   public function __construct($x, $y, $radius, DrawingAPI $drawingAPI) {
       $this->x = $x;
       $this->y = $y;
       $this->radius = $radius; 
       $this->drawingAPI = $drawingAPI;
   }
   // low-level i.e. Implementation specific
   public function draw() { $this->drawingAPI->drawCircle($this->x, $this->y, $this->radius); }   
   // high-level i.e. Abstraction specific
   public function resizeByPercentage($pct) { $this->radius *= $pct; }
}

/** "Client" */
$shapes = array();
$shapes[] = new CircleShape(1, 2, 3, new DrawingAPI1());
$shapes[] = new CircleShape(5, 7, 11, new DrawingAPI2());

foreach ($shapes as $shape) {
  $shape->resizeByPercentage(2.5);
  $shape->draw();
}

[edytuj] Python

The following Python 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

 class CircleShape:
   def __init__(self,x,y,r,da):
       self.x = x
       self.y = y
       self.r = r
       self.da = da
   def draw(self): self.da.drawCircle(self.x,self.y,self.r)
   def resizeByPercentage(self,pct): self.r *= pct

 class DrawingAPI2:
   def drawCircle(self,x,y,r): 
       print "API2.circle at %f:%f radius %f" % (x,y,r)

 class DrawingAPI1:
   def drawCircle(self,x,y,r): 
       print "API1.circle at %f:%f radius %f" % (x,y,r)

 if __name__ == '__main__':
   shapes = [CircleShape(1,2,3,DrawingAPI1()), CircleShape(5,7,11,DrawingAPI2())]
   for shape in shapes:
       shape.resizeByPercentage(2.5)
       shape.draw()

[edytuj] Ruby

wyjście:

API1.circle at 1.000000:2.000000 radius 7.500000
API2.circle at 5.000000:7.000000 radius 27.500000

 class CircleShape
   def initialize(x, y, r, da)
       @x = x
       @y = y
       @r = r
       @da = da
   end
   def draw; @da.drawCircle(@x, @y, @r); end
   def resizeByPercentage(pct); @r *= pct; end
 end
 class DrawingAPI1
   def drawCircle(x,y,r)
     printf "API1.circle at %f:%f radius %f", x, y, r
   end
 end
 class DrawingAPI2
   def drawCircle(x,y,r)
     printf "API2.circle at %f:%f radius %f", x, y, r
   end
 end
 
 shapes = [CircleShape.new(1, 2, 3, DrawingAPI1.new), CircleShape.new(5, 7, 11, DrawingAPI2.new)]
 shapes.each do |shape|
   shape.resizeByPercentage(2.5)
   shape.draw
 end
THIS WEB:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2008 (no images)

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - bcl - be - be_x_old - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - co - cr - crh - cs - csb - cu - cv - cy - da - de - diq - dsb - dv - dz - ee - el - eml - en - eo - es - et - eu - ext - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gan - gd - gl - glk - gn - got - gu - gv - ha - hak - haw - he - hi - hif - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kaa - kab - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mdf - mg - mh - mi - mk - ml - mn - mo - mr - mt - mus - my - myv - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - quality - rm - rmy - rn - ro - roa_rup - roa_tara - ru - rw - sa - sah - sc - scn - sco - sd - se - sg - sh - si - simple - sk - sl - sm - sn - so - sr - srn - ss - st - stq - su - sv - sw - szl - ta - te - tet - tg - th - ti - tk - tl - tlh - tn - to - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu -

Static Wikipedia 2007:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu

Static Wikipedia 2006:

aa - ab - af - ak - als - am - an - ang - ar - arc - as - ast - av - ay - az - ba - bar - bat_smg - be - bg - bh - bi - bm - bn - bo - bpy - br - bs - bug - bxr - ca - cbk_zam - cdo - ce - ceb - ch - cho - chr - chy - closed_zh_tw - co - cr - cs - csb - cu - cv - cy - da - de - diq - dv - dz - ee - el - eml - en - eo - es - et - eu - fa - ff - fi - fiu_vro - fj - fo - fr - frp - fur - fy - ga - gd - gl - glk - gn - got - gu - gv - ha - haw - he - hi - ho - hr - hsb - ht - hu - hy - hz - ia - id - ie - ig - ii - ik - ilo - io - is - it - iu - ja - jbo - jv - ka - kg - ki - kj - kk - kl - km - kn - ko - kr - ks - ksh - ku - kv - kw - ky - la - lad - lb - lbe - lg - li - lij - lmo - ln - lo - lt - lv - map_bms - mg - mh - mi - mk - ml - mn - mo - mr - ms - mt - mus - my - mzn - na - nah - nap - nds - nds_nl - ne - new - ng - nl - nn - no - nov - nrm - nv - ny - oc - om - or - os - pa - pag - pam - pap - pdc - pi - pih - pl - pms - ps - pt - qu - rm - rmy - rn - ro - roa_rup - roa_tara - ru - ru_sib - rw - sa - sc - scn - sco - sd - se - searchcom - sg - sh - si - simple - sk - sl - sm - sn - so - sq - sr - ss - st - su - sv - sw - ta - te - test - tet - tg - th - ti - tk - tl - tlh - tn - to - tokipona - tpi - tr - ts - tt - tum - tw - ty - udm - ug - uk - ur - uz - ve - vec - vi - vls - vo - wa - war - wo - wuu - xal - xh - yi - yo - za - zea - zh - zh_classical - zh_min_nan - zh_yue - zu