Design Pattern: Bridge Pattern in PHP

Bridge Pattern separates the abstraction from implementation, and creates a loose connection between those, so that they can work independently.

This article is about Bridge pattern implementation in PHP. Check the implementation details and examples.

Implementation

Here are the steps to implement Bridge pattern in PHP-

  • Create an interface for the implementor classes.
  • Create implementor classes and implement the interface.
  • Create an abstract class for the abstraction classes. Define a property to hold a reference to an implementor object.
  • Create classes for the abstraction implementation and extend the abstract class.
  • While creating the abstraction class object, pass the implementor object. And set that to the implementor property reference.

Here is a simple example Bridge pattern implementation in PHP-

<?php
// Bridge pattern implementation in PHP

// Plugin interface
interface PluginI {
    function pluginOperation1(): void;
}

// First plugin
class Plugin1 implements PluginI {
    public function pluginOperation1(): void {
        echo "Plugin 1: operation 1n";
    }
}

// Second plugin
class Plugin2 implements PluginI {
    public function pluginOperation1(): void {
        echo "Plugin 2: operation 1n";
    }
}

// Module interface
abstract class ModuleI {
    protected PluginI $plugin;

    public function __construct(PluginI $plugin) {
        $this->plugin = $plugin;
    }

    public abstract function moduleOperation1(): void;
}

// First module
class Module1 extends ModuleI {
    public function moduleOperation1(): void {
        echo "Module 1: operation 1n";

        $this->plugin->pluginOperation1();
    }
}

// Second module
class Module2 extends ModuleI {
    public function moduleOperation1(): void {
        echo "Module 2: operation 1n";

        $this->plugin->pluginOperation1();
    }
}


// Demo
$module1 = new Module1(new Plugin2());
$module1->moduleOperation1();

Here is the output of the above implementation-

Module 1: operation 1
Plugin 2: operation 1

Examples

Check the following examples of Bridge pattern implementation-

Example #1: UI Elements

In this example, we have 2 separate set of classes, implementing 2 separate interfaces.

One type of class represents colors and another set represents some UI elements.

Color Interface

  • Create file “Color.php”.
  • Create interface “Color”.
  • Declare method – “setColor”. We can define methods as per the requirement.
<?php
// Color.php

namespace BigBoxCodeDesignPatternBridgeUiElement;

interface Color {
    function setColor(): void;
}

Red [Color Schema]

  • Create file “Red.php”.
  • Cretae class “Red”, and implement interface “Color”.
<?php
// Red.php

namespace BigBoxCodeDesignPatternBridgeUiElement;

class Red implements Color {
    public function setColor(): void {
        echo "Setting proper color for Red color scheman";
    }
}

Green [Color Schema]

  • Create file “Green.php”.
  • Create class “Green”.
  • Implement interface “Color” for the class.
<?php
// Green.php

namespace BigBoxCodeDesignPatternBridgeUiElement;

class Green implements Color {
    public function setColor(): void {
        echo "Setting proper color for Green color scheman";
    }
}

Blue [Color Schema]

  • Create file “Blue.php”.
  • Define class “Blue” and implement interface “Color”.
<?php
// Blue.php

namespace BigBoxCodeDesignPatternBridgeUiElement;


class Blue implements Color {
    public function setColor(): void {
        echo "Setting proper color for Blue color scheman";
    }
}

UI Element Interface

  • Create file “UiElement.php”.
  • Define abstract class “UIElement”.
  • Define a protected property “$color” of type “Color”. In the constructor accept a parameter of type “Color” and set that to the “$color” property.
  • Declare an abstract method “printElement”.
<?php
// UiElement.php

namespace BigBoxCodeDesignPatternBridgeUiElement;

abstract class UIElement {
    protected Color $color;

    public function __construct(Color $color) {
        $this->color = $color;
    }

    abstract function printElement(): void;
}

Button [UI Element]

  • Create file “Button.php”.
  • Define class “Button”.
  • Extend “UIElement” for the “Button” class. Define method “printElement” as part of the extension.
  • In the constructor, accept a color parameter and pass that to the parent constructor.
<?php
// Button.php

namespace BigBoxCodeDesignPatternBridgeUiElement;


class Button extends UIElement {
    public function __construct(Color $color) {
        parent::__construct($color);
    }

    public function printElement(): void {
        $this->color->setColor();

        echo "Printing Buttonn";
    }
}

Input [UI Element]

  • Create file “Input.php”.
  • Define class “Input” and extend “UIElement”.
  • In the constructor call the parent to construct and pass color.
<?php
// Input.php

namespace BigBoxCodeDesignPatternBridgeUiElement;

class Input extends UIElement {
    public function __construct(Color $color) {
        parent::__construct($color);
    }

    public function printElement(): void {
        $this->color->setColor();

        echo "Printing Inputn";
    }
}

Table [UI Element]

  • Create file “Table.php”.
  • Define class “Table”.
  • Extend “UIElement” for the class.
<?php
// Table.php

namespace BigBoxCodeDesignPatternBridgeUiElement;


class Table extends UIElement {
    public function __construct(Color $color) {
        parent::__construct($color);
    }

    public function printElement(): void {
        $this->color->setColor();

        echo "Printing Tablen";
    }
}

Demo

In the client, pass an object of type “Color” (Red/Green/Blue) while creating an object of type “UIElement”(Table/Input/Button).

<?php
// demo.php

require __DIR__ . '/../../vendor/autoload.php';

use BigBoxCodeDesignPatternBridgeUiElementBlue;
use BigBoxCodeDesignPatternBridgeUiElementButton;
use BigBoxCodeDesignPatternBridgeUiElementGreen;
use BigBoxCodeDesignPatternBridgeUiElementInput;
use BigBoxCodeDesignPatternBridgeUiElementRed;
use BigBoxCodeDesignPatternBridgeUiElementTable;

$table = new Table(new Red());
$table->printElement();

$input = new Input(new Green());
$input->printElement();

$button = new Button(new Blue());
$button->printElement();

$button2 = new Button(new Red());
$button2->printElement();

Output

Output will be as follows-

Setting proper color for Red color schema
Printing Table

Setting proper color for Green color schema
Printing Input

Setting proper color for Blue color schema
Printing Button

Setting proper color for Red color schema
Printing Button

Example #2: Transport Seat

Here we have 2 group of classes-

  • One group represents type of seat- Business class or Economy.
  • Another group represents transport – Train, Plane, etc.

We want an implementation to select seat of a transport.

Seat Interface

  • Create file “Seat.php”.
  • Create interface “Seat”.
  • Declare method “selectSeat”.
<?php
// Seat.php

namespace BigBoxCodeDesignPatternBridgeTransportSeat;

interface Seat {
    function selectSeat(): void;
}

Business Class Seat [Seat Type]

  • Create file “BusinessClassSeat.php”.
  • Define class “BusinessClassSeat”.
  • Implement the “Seat” interface.
<?php
// BusinessClassSeat.php

namespace BigBoxCodeDesignPatternBridgeTransportSeat;

class BusinessClassSeat implements Seat {
    public function selectSeat(): void {
        echo "Select an Business class seatn";
    }
}

Economy Class Seat [Seat Type]

  • Create file “EconomyClassSeat.php”.
  • Create class “EconomyClassSeat” and implement the “Seat” interface.
<?php
// EconomyClassSeat.php

namespace BigBoxCodeDesignPatternBridgeTransportSeat;


class EconomyClassSeat implements Seat {
    public function selectSeat(): void {
        echo "Select an Economy class seatn";
    }
}

Transport Interface

  • Create file “Transport.php”.
  • Define abstract class “Transport”.
  • Define a property “$seat” of type “Seat” and set that in the constructor.
  • Declare a method “selectTransport”, and make it abstract.
<?php
// Transport.php

namespace BigBoxCodeDesignPatternBridgeTransportSeat;

abstract class Transport {
    public function __construct(protected Seat $seat) {
    }

    abstract function selectTransport(): void;
}

Plane [Transport]

  • Create file “Plane.php”.
  • Define class “Plane”.
  • Extend “Transport”, and define “selectTransport”.
<?php
// Plane.php

namespace BigBoxCodeDesignPatternBridgeTransportSeat;

class Plane extends Transport {
    public function __construct(Seat $seat) {
        parent::__construct($seat);
    }

    public function selectTransport(): void {
        echo "Plane selected for transportn";

        $this->seat->selectSeat();
    }
}

Train [Transport]

  • Create file “Train.php”.
  • Define class “Train”. Extend Transport for this class.
<?php
// Train.php

namespace BigBoxCodeDesignPatternBridgeTransportSeat;


class Train extends Transport {
    public function __construct(Seat $seat) {
        parent::__construct($seat);
    }

    public function selectTransport(): void {
        echo "Train selected for transportn";
        $this->seat->selectSeat();
    }
}

Demo

In the client, pass an object of type “Seat” (BusinessClassSeat/EconomyClassSeat), while creating a “Transport”(Train/Plane) object.

<?php
// demo.php

require __DIR__ . '/../../vendor/autoload.php';

use BigBoxCodeDesignPatternBridgeTransportSeatBusinessClassSeat;
use BigBoxCodeDesignPatternBridgeTransportSeatEconomyClassSeat;
use BigBoxCodeDesignPatternBridgeTransportSeatPlane;
use BigBoxCodeDesignPatternBridgeTransportSeatTrain;

$plane = new Plane(new BusinessClassSeat());
$plane->selectTransport();

$plane2 = new Plane(new EconomyClassSeat());
$plane2->selectTransport();

$train = new Train(new EconomyClassSeat());
$train->selectTransport();

Output

We will get the following output.

Plane selected for transport
Select an Business class seat

Plane selected for transport
Select an Economy class seat

Train selected for transport
Select an Economy class seat

Source Code

Use the following link to get the source code:

Other Code Implementations

Use the following links to check Bridge pattern implementation in other programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.