Bridge Pattern separates the abstraction from implementation, and creates a loose connection between those, so that they can work independently.
NOTES
In this article, we discuss the implementation of the Bridge Pattern in PHP.
See the Bridge in other languages in the “Other Code Implementations” section. Or, use the link below to check the details of the Bridge Pattern-
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.