Backend DevelopmentDesign Patterns

Describing PHP Bridge Design Pattern With an Example

bridge design pattern in php

Another structural design pattern is the Bridge design pattern which represent two collection of strategies where each one of the first collection can make use of each one in the second collection.

 

 

When talking about the Bridge design pattern we remember the Strategy pattern although the strategy pattern is a behavioral pattern and the Bridge pattern is a structural pattern but they have some similarities. In the strategy pattern you chose between two strategies. In the Bridge pattern you have two collection of strategies and each strategy in the first collection can make use of each strategy in the second collection. So in other words the Bridge pattern is a strategy pattern but in large scale.

The first collection in the Bridge pattern is the abstractions while the second collection is the implementations. The abstractions doesn’t need to know how the implementation work. Just all it need it know is how to call the implementation.

 

php bridge design pattern diagram

Terminology

 

Abstractions

interface IOAbstraction {
   function call();
}

class Class1 implements IOAbstraction
{
   
} 

class Class2 implements IOAbstraction
{
   
} 

class Class3 implements IOAbstraction
{
   
} 

.......
.......

Implementations

interface IOImplementation {
   function handle();
}
class Class1 implements IOImplementation
{
}
class Class2 implements IOImplementation
{
}

Example

Let’s see an example to clarify the idea, suppose we have three types of applications as follows: Web application, Desktop application, and Mobile Application. These three different applications needs to access and manipulate database where the database driver may be Mysql database or MsSqlServer database or Oracle database.

<?php
interface IOApplication
{
    public function setDatabaseDriver(IODatabaseDriver $dbDriver);

    public function query($query);
}

abstract class Application implements IOApplication
{
   protected $dbDriver;

   public function setDatabaseDriver(IODatabaseDriver $dbDriver)
   {
       $this->dbDriver = $dbDriver;
   }
}

class WebApp extends Application
{
    public function query($query)
    {
	$query .= "\n\n running Web app query\n";

        return $this->dbDriver->handleQuery($query);
    }
}

class MobileApp extends Application
{
    public function query($query)
    {
	$query .= "\n\n running mobile app query\n";

        return $this->dbDriver->handleQuery($query);
    }
}

interface IODatabaseDriver
{
    public function handleQuery($query);
}

class MysqlServerDriver implements IODatabaseDriver
{
    public function handleQuery($query)
    {
        echo "\nUsing the mysql server driver: ".$query;
    }
}

class MsSqlServerDriver implements IODatabaseDriver
{
    public function handleQuery($query)
    {
        echo "\nUsing the ms sql server driver: ".$query;
    }
}

class OracleDriver implements IODatabaseDriver
{
    public function handleQuery($query)
    {
        echo "\nUsing the oracle driver: ".$query;
    }
}

echo "<pre>";

$webApp = new WebApp();
$webApp->setDatabaseDriver(new MysqlServerDriver());
echo $webApp->query("select * from table");

$webApp->setDatabaseDriver(new OracleDriver());
echo $webApp->query("select * from table");

$mobileApp = new MobileApp();
$mobileApp->setDatabaseDriver(new OracleDriver());
echo $mobileApp->query("select * from table");

echo "</pre>";

As you see in the above code i have added the interfaces and classes that represent the basic components of the Bridge pattern. As we mentioned earlier that the bridge pattern have two main components.

The first component is the abstraction collection of strategies and in this example the abstraction component represent the application type. The abstraction component here have no implementations in it’s own but call the other collections implementations based on database driver type.

At first i have added the interface for the first collection IOApplication inside this interface an important function called setDatabaseDriver(IODatabaseDriver $dbDriver). This function is to set a reference of the second component in first component to be able to call the second component handleQuery($query) method, so i have added another abstract class to handle the setDatabaseDriver() method like this:

abstract class Application implements IOApplication
{
   protected $dbDriver;

   public function setDatabaseDriver(IODatabaseDriver $dbDriver)
   {
       $this->dbDriver = $dbDriver;
   }
}

I have added this abstract class so as to override this method once and not on all classes.

Then i added the abstraction classes which are WebApp, DesktopApp, and MobileApp. the abstraction classes must extend from base class Application and must override the function query() for example in the WepApp class:

class WebApp extends Application
{
    public function query($query)
    {
	$query .= "\n\n running Web app query\n";

        return $this->dbDriver->handleQuery($query);
    }
}

The most important part here is calling the handleQuery() method from IODatabaseDriver interface and this achieves the area of responsibility principal. This also achieves the main principal of this pattern is the first collection of strategies makes use of the second collection of strategies.

The second collection must contain the real implementations of the Api, in this case i just printed some text but in real world scenario the Database driver must handle querying the database.

class MysqlServerDriver implements IODatabaseDriver
{
    public function handleQuery($query)
    {
        echo "\nUsing the mysql server driver: ".$query;
    }
}

 

 

5 4 votes
Article Rating

What's your reaction?

Excited
2
Happy
0
Not Sure
2
Confused
2

You may also like

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments