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 1\n";
    }
}

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

// 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 1\n";

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

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

        $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 BigBoxCode\DesignPattern\Bridge\UiElement;

interface Color {
    function setColor(): void;
}

Red [Color Schema]

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

namespace BigBoxCode\DesignPattern\Bridge\UiElement;

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

Green [Color Schema]

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

namespace BigBoxCode\DesignPattern\Bridge\UiElement;

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

Blue [Color Schema]

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

namespace BigBoxCode\DesignPattern\Bridge\UiElement;


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

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 BigBoxCode\DesignPattern\Bridge\UiElement;

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 BigBoxCode\DesignPattern\Bridge\UiElement;


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

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

        echo "Printing Button\n";
    }
}

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 BigBoxCode\DesignPattern\Bridge\UiElement;

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

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

        echo "Printing Input\n";
    }
}

Table [UI Element]

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

namespace BigBoxCode\DesignPattern\Bridge\UiElement;


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

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

        echo "Printing Table\n";
    }
}

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 BigBoxCode\DesignPattern\Bridge\UiElement\Blue;
use BigBoxCode\DesignPattern\Bridge\UiElement\Button;
use BigBoxCode\DesignPattern\Bridge\UiElement\Green;
use BigBoxCode\DesignPattern\Bridge\UiElement\Input;
use BigBoxCode\DesignPattern\Bridge\UiElement\Red;
use BigBoxCode\DesignPattern\Bridge\UiElement\Table;

$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 BigBoxCode\DesignPattern\Bridge\TransportSeat;

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 BigBoxCode\DesignPattern\Bridge\TransportSeat;

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

Economy Class Seat [Seat Type]

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

namespace BigBoxCode\DesignPattern\Bridge\TransportSeat;


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

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 BigBoxCode\DesignPattern\Bridge\TransportSeat;

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 BigBoxCode\DesignPattern\Bridge\TransportSeat;

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

    public function selectTransport(): void {
        echo "Plane selected for transport\n";

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

Train [Transport]

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

namespace BigBoxCode\DesignPattern\Bridge\TransportSeat;


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

    public function selectTransport(): void {
        echo "Train selected for transport\n";
        $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 BigBoxCode\DesignPattern\Bridge\TransportSeat\BusinessClassSeat;
use BigBoxCode\DesignPattern\Bridge\TransportSeat\EconomyClassSeat;
use BigBoxCode\DesignPattern\Bridge\TransportSeat\Plane;
use BigBoxCode\DesignPattern\Bridge\TransportSeat\Train;

$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.