Kody źródłowe/Most (wzorzec projektowy)

Z Wikibooks, biblioteki wolnych podręczników.
Przejdź do nawigacji Przejdź do wyszukiwania
Most (wzorzec projektowy)
Kod źródłowy
Kody źródłowe programów stosujących wzorzec projektowy mostu
Wikipedia
Zobacz w Wikipedii hasło Most


Java[edytuj]

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

C++[edytuj]

#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;
}


C#[edytuj]

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

Perl[edytuj]

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


PHP[edytuj]

wyjście:

API1.circle at 1:2 radius 7.5
API2.circle at 5:7 radius 27.5
 <?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();
 }
?>


Python[edytuj]

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 __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()


Ruby[edytuj]

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