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.