Híd programtervezési minta
A híd programtervezési minta egy szoftverfejlesztésben használt tervezési minta, mely azt jelenti, hogy "különválasztjuk az absztrakciót az implementációjától, hogy a kettőt függetlenül lehessen variálni." A híd egységbe zárást, aggregációt, és öröklődést használ, hogy a felelősségi köröket különböző osztályokba különítse el.

A híd mintára kétrétegű absztrakcióként is tekinthetünk. Ez általában azt jelenti, hogy adva van két interfész (a híd két "pillére"), az egyik magaszintű művelet(ek)et, a másik alacsonyszintű művelet(ek)et deklarál; és a magasszintű interfész implementációi az alacsonyszintű interfész tetszőleges implementációjával együttműködnek (és azt a konstruktorban veszik át). Ez lehetővé teszi, hogy a rétegek egymástól függetlenül cserélhetők legyenek.

Előfordul, hogy csak egy fix implementáció létezik, ez a minta Pimpl idiómaként is ismert a C++ világban.

A híd minta nem azonos az illesztő (adapter) mintával, bár a híd mintát gyakran valósítják meg az osztály illesztő minta felhasználásával (ld. a lenti példákat).

A híd minta a függőség befecskendezésének (dependency injection) egyik lehetséges módja.

Struktúra

 Abstraction (absztrakt osztály)
definiálja az absztrakt interfészt
 karbantarja az Implementor referenciát.
 RefinedAbstraction (normál osztály)
 kiterjeszti  Abstraction által definiált interfészt
 Implementor (interfész)
 definiálja az interfészt az implementation osztályokra
 ConcreteImplementor (normál osztály)
 megvalósítja az Implementor interfészt

Példa

Java 
A következő Java program alakzatok kirajzolásának példáján keresztül illusztrálja a híd mintát.

/** "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" */
abstract class Shape {
    protected DrawingAPI drawingAPI;

    protected Shape(DrawingAPI drawingAPI){
        this.drawingAPI = drawingAPI;
    }

    public abstract void draw();                             // low-level
    public abstract void resizeByPercentage(double pct);     // high-level
}

/** "Refined Abstraction" */
class CircleShape extends Shape {
    private double x, y, radius;
    public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {
        super(drawingAPI);
        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 BridgePatternExample {
    public static void main(String[] args) {
        Shape[] shapes = new Shape[] {
            new CircleShape(1, 2, 3, new DrawingAPI1()),
            new CircleShape(5, 7, 11, new DrawingAPI2()),
        };

        for (Shape shape : shapes) {
            shape.resizeByPercentage(2.5);
            shape.draw();
        }
    }
}

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

PHP 
PHP nyelvű példa.
interface DrawingAPI {
    function drawCircle($dX, $dY, $dRadius);
}

class DrawingAPI1 implements DrawingAPI {

    public function drawCircle($dX, $dY, $dRadius) {
        echo "API1.circle at $dX:$dY radius $dRadius.<br/>";
    }
}

class DrawingAPI2 implements DrawingAPI {

    public function drawCircle($dX, $dY, $dRadius) {
        echo "API2.circle at $dX:$dY radius $dRadius.<br/>";
    }
}

abstract class Shape {

    protected $oDrawingAPI;

    public abstract function draw();
    public abstract function resizeByPercentage($dPct);

    protected function __construct(DrawingAPI $oDrawingAPI) {
        $this->oDrawingAPI = $oDrawingAPI;
    }
}

class CircleShape extends Shape {

    private $dX;
    private $dY;
    private $dRadius;

    public function __construct($dX, $dY, $dRadius, DrawingAPI $oDrawingAPI) {
        parent::__construct($oDrawingAPI);
        $this->dX = $dX;
        $this->dY = $dY;
        $this->dRadius = $dRadius;
    }

    public function draw() {
        $this->oDrawingAPI->drawCircle(
                $this->dX,
                $this->dY,
                $this->dRadius
        );
    }

    public function resizeByPercentage($dPct) {
        $this->dRadius *= $dPct;
    }
}

class Tester {

    public static function main()  {
        $aShapes = array(
            new CircleShape(1, 3, 7,  new DrawingAPI1()),
            new CircleShape(5, 7, 11, new DrawingAPI2()),
        );

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

Tester::main();

Kimenete:
 API1.circle at 1:3 radius 17.5
 API2.circle at 5:7 radius 27.5

Scala 
Scala nyelvű példa.
trait DrawingAPI {
  def drawCircle(x: Double, y: Double, radius: Double)
}

class DrawingAPI1 extends DrawingAPI {
  def drawCircle(x: Double, y: Double, radius: Double) = println(s"API #1 $x $y $radius")
}

class DrawingAPI2 extends DrawingAPI {
  def drawCircle(x: Double, y: Double, radius: Double) = println(s"API #2 $x $y $radius")
}

abstract class Shape(drawingAPI: DrawingAPI) {
  def draw()
  def resizePercentage(pct: Double)
}

class CircleShape(x: Double, y: Double, var radius: Double, drawingAPI: DrawingAPI)
    extends Shape(drawingAPI: DrawingAPI) {

  def draw() = drawingAPI.drawCircle(x, y, radius)

  def resizePercentage(pct: Double) { radius *= pct }
}

object BridgePatternExample {
  def main(args: Array[String]) {
    Seq (
    new CircleShape(1, 3, 5, new DrawingAPI1),
    new CircleShape(4, 5, 6, new DrawingAPI2)
    ) foreach { x => 
        x.resizePercentage(3)
        x.draw()            
      }    
  }
}

Kapcsolódó szócikkek
Sablon metódus tervezési minta
Stratégia tervezési minta
Illesztő tervezési minta

Jegyzetek

További információk

Bridge in UML and in LePUS3 (a formal modelling language)
  From:

Fordítás

Programtervezési minták
C Sharp-kódpéldák
Java-kódpéldák
A híd programtervezési minta egy szoftverfejlesztésben használt tervezési minta , mely azt jelenti , hogy " különválasztjuk az absztrakciót az implementációjától , hogy a kettőt függetlenül lehessen variálni . " A híd egységbe zárást , aggregációt , és öröklődést használ , hogy a felelősségi köröket különböző osztályokba különítse el . A híd mintára kétrétegű absztrakcióként is tekinthetünk . Ez általában azt jelenti , hogy adva van két interfész ( a híd két " pillére " ) , az egyik magaszintű művelet( ek) et , a másik alacsonyszintű művelet( ek) et deklarál ; és a magasszintű interfész implementációi az alacsonyszintű interfész tetszőleges implementációjával együttműködnek ( és azt a konstruktorban veszik át ) . Ez lehetővé teszi , hogy a rétegek egymástól függetlenül cserélhetők legyenek . Előfordul , hogy csak egy fix implementáció létezik , ez a minta Pimpl idiómaként is ismert a C++ világban . A híd minta nem azonos az illesztő ( adapter ) mintával , bár a híd mintát gyakran valósítják meg az osztály illesztő minta felhasználásával ( ld. a lenti példákat ) . A híd minta a függőség befecskendezésének ( dependency injection ) egyik lehetséges módja . Struktúra Abstraction ( absztrakt osztály ) definiálja az absztrakt interfészt karbantarja az Implementor referenciát . RefinedAbstraction ( normál osztály ) kiterjeszti Abstraction által definiált interfészt Implementor ( interfész ) definiálja az interfészt az implementation osztályokra ConcreteImplementor ( normál osztály ) megvalósítja az Implementor interfészt Példa Java A következő Java program alakzatok kirajzolásának példáján keresztül illusztrálja a híd mintát . / * * " Implementor " * / interface DrawingAPI { public void drawCircle( double x , double y , double radius ) ; } / * * " ConcreteImplementor " 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 * / 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 " * / abstract class Shape { protected DrawingAPI drawingAPI ; protected Shape( DrawingAPI drawingAPI ) { this.drawingAPI = drawingAPI ; } public abstract void draw ( ) ; / / low-level public abstract void resizeByPercentage( double pct ) ; / / high-level } / * * " Refined Abstraction " * / class CircleShape extends Shape { private double x , y , radius ; public CircleShape( double x , double y , double radius , DrawingAPI drawingAPI ) { super( drawingAPI ) ; 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 BridgePatternExample { public static void main( String [ ] args ) { Shape [ ] shapes = new Shape [ ] { new CircleShape ( 1 , new DrawingAPI1 ( ) ) , new CircleShape ( 5 , new DrawingAPI2 ( ) ) , } ; for ( Shape shape \ : shapes ) { shape.resizeByPercentage ( 2.5 ) ; shape.draw ( ) ; } } } Kimenete : API1.circle at000000:2.000000 radius5000000 API2.circle at000000:7.000000 radius500000 PHP PHP nyelvű példa. interface DrawingAPI { function drawCircle( $dX , $dY , $dRadius ) ; } class DrawingAPI1 implements DrawingAPI { public function drawCircle( $dX , $dY , $dRadius ) { echo " API1.circle at $dX : $dY radius $dRadius.<br/> " ; } } class DrawingAPI2 implements DrawingAPI { public function drawCircle( $dX , $dY , $dRadius ) { echo " API2.circle at $dX : $dY radius $dRadius. <br/> " ; } } abstract class Shape { protected $oDrawingAPI ; public abstract function draw ( ) ; public abstract function resizeByPercentage( $dPct ) ; protected function __construct ( DrawingAPI $oDrawingAPI ) { $this->oDrawingAPI = $oDrawingAPI ; } } class CircleShape extends Shape { private $dX ; private $dY ; private $dRadius ; public function __construct ( $dX , $dY , $dRadius , DrawingAPI $oDrawingAPI ) { parent : : __construct ( $oDrawingAPI ) ; $this->dX = $dX ; $this->dY = $dY ; $this->dRadius = $dRadius ; } public function draw ( ) { $this->oDrawingAPI->drawCircle ( $this->dX , $this->dY , $this->dRadius ) ; } public function resizeByPercentage( $dPct ) { $this->dRadius *= $dPct ; } } class Tester { public static function main ( ) { $aShapes = array ( new CircleShape ( 1 , new DrawingAPI1 ( ) ) , new CircleShape ( 5 , new DrawingAPI2 ( ) ) , ) ; foreach ( $aShapes as $shape ) { $shape->resizeByPercentage( 2.5 ) ; $shape->draw ( ) ; } } } Tester: : main ( ) ; Kimenete : API1.circle at3 radius5 API2.circle at7 radius5 Scala Scala nyelvű példa. trait DrawingAPI { def drawCircle ( x : Double , y : Double , radius : Double ) } class DrawingAPI1 extends DrawingAPI { def drawCircle ( x : Double , y : Double , radius : Double ) = println( s" API #1 $x $y $radius " ) } class DrawingAPI2 extends DrawingAPI { def drawCircle ( x : Double , y : Double , radius : Double ) = println( s" API #2 $x $y $radius " ) } abstract class Shape( drawingAPI : DrawingAPI ) { def draw ( ) def resizePercentage( pct : Double ) } class CircleShape ( x : Double , y : Double , var radius : Double , drawingAPI : DrawingAPI ) extends Shape( drawingAPI : DrawingAPI ) { def draw ( ) = drawingAPI.drawCircle ( x , y , radius ) def resizePercentage( pct : Double ) { radius *= pct } } object BridgePatternExample { def main( args : Array[ String ] ) { Seq ( new CircleShape ( 1 , new DrawingAPI1 ) , new CircleShape ( 4 , new DrawingAPI2 ) ) foreach { x => x.resizePercentage ( 3 ) x.draw ( ) } } } Kapcsolódó szócikkek Sablon metódus tervezési minta Stratégia tervezési minta Illesztő tervezési minta Jegyzetek További információk Bridge in UML and in LePUS3 ( a formal modelling language ) From : Fordítás Programtervezési minták C Sharp-kódpéldák Java-kódpéldák