Introducing Bridge Classes with PHP 5

The bridge class, or what’s commonly known as the bridge pattern, lets you create a class with its abstract functionality and implementation residing on different class hierarchies. This lets you decouple the class from its concrete application. This article, the first of three parts, introduces you to the bridge pattern and its uses.


If you’re a PHP developer who has a significant background in developing object-based applications, then possibly you’ll agree with me that when it comes to implementing an approach for decoupling the logic of a given class from its concrete implementation, there are some trusted techniques that can be applied successfully.

Among others, the factory pattern is one of the cases that best applies the concept that I described above. When this pattern is used, it’s possible to create a class that simply “returns” objects to calling code, without having to worry about how these objects behave inside the context of a given application or even how long they persist during the request of multiple PHP files.

However, and now speaking more specifically, using a factory class inside an application implies that you can decouple the logic that stands behind all the created objects from the corresponding creator. At the same time, this means that multiple objects (at least two) are involved in the creation process. Without a doubt, the situation that I illustrated a few lines ago should bring up the following question: is it feasible to work with only one class (not many classes) that can be decoupled from its concrete implementation?

Fortunately, the answer to the above inquiry is a loud "Yes!" To give you an example covering the topic in question, think about an abstract class, where its implementation is most of the time separated from its declaration. That sounds really good, and indeed the application of abstract classes is an important link in the chain of object-oriented programming, but definitely it’s not the only approach used for separating a class from its implementation.

Assuming that you’re interested in learning an alternative approach for achieving the mentioned decoupling process, let me now introduce the concept of “bridge” classes, or what’s more generally known as the bridge pattern. In this specific case, it’s possible to create a class where its respective abstract functionality and implementation reside on different class hierarchies, in this way allowing you to decouple the class in question from its concrete application. And best of all, the referenced procedure can be performed without using abstract classes at all.

Of course, I’m pretty certain that all this theory on applying the bridge pattern seems to be a hard thing to grasp, but in fact it’s much simpler than you think. Thus, in this series, which is comprised of three tutorials, I’m going to teach you how to create and use bridge classes with PHP 5, by showing you numerous hands-on examples that can be easily included in your own PHP applications with minor modifications.

Ready to learn more on how to apply the bridge design pattern with PHP? All right, let’s no waste more time in preliminaries and begin now!

{mospagebreak title=Introducing the basics of the bridge pattern}

Naturally, a good place to start demonstrating the creation and usage of bridge objects with PHP 5 is with developing a practical example where these types of objects are utilized to perform a given task.

In this case, the example that I’m going to set up will be based upon creating first a target object, called “Message,” which will be tasked with displaying some trivial strings to the browser. Next, I’m going to define a bridge class that will be capable of saving the mentioned target object to different storage locations, like a plain text file, an array structure and a simple cookie.

Hopefully, after you see how this bridge class looks, you’ll realize how its instantiation can be separated from its corresponding implementation, since both things will reside on different class hierarchies.

So far, so good. The process for building a bridge class seems really straightforward, therefore let me show you the first target class involved in this creation process. As I said before , it is named “Message,” and its simple signature is shown below:

// define 'Message' class (target object for 'BridgeObjectSaver' class) class Message{ private $message; public function __construct($message='Default Message'){ if(!$message||!is_string($message)||strlen
($message)>255){ throw new Exception('Invalid input message'); } $this->message=$message; } public function getMessage(){ return $this->message; } }

As illustrated above, the “Message” sample class is really simple to understand. All this class does is accept an input string as the unique parameter, which will be returned to calling code with the trivial purpose of being displayed on the browser, or receiving similar processing. Extremely easy, right?

Well, I have to admit that the previous target class is rather primitive, but for my purpose of showing you how a bridge class can be created with PHP 5, the definition for this class is more than enough, at least for now.

Therefore, having shown the signature of the respective “Message” class, it’s a good time to leap forward and learn how to build a bridge class. This class will use “Message” objects and save them to different storage locations, including text files, arrays and cookies respectively.

Do you want to see how this brand new bridge class will be created? All right, jump into the following section and keep reading.

{mospagebreak title=Implementing the bridge pattern’s core logic}

In consonance with the intrinsic definition of the bridge pattern, it should be possible to separate a given class from its concrete implementation (without using abstract classes at all), since both of them will reside on different class hierarchies. This concept will be much easier to grasp if you take a look at the signature of the following bridge class, which takes up objects of type “Message” and saves them to different locations.

That being said, the definition for this brand new class is as follows:

// define class 'BridgeObjectSaver' class BridgeObjectSaver{ private $messageObj; private $objSaver; public function __construct(Message $messageObj,$saveCommand){ if(!in_array($saveCommand,array('array',
'file','cookie'))){ throw new Exception('Invalid save command'); } $this->messageObj=$messageObj; // target object is saved to array if($saveCommand=='array'){ $this->objSaver=newObjectToArraySaver(); } // target object is saved to file elseif($saveCommand=='file'){ $this->objSaver=new ObjectToFileSaver(); } // target object is saved to a cookie else{ $this->objSaver=new ObjectToCookieSaver(); } } public function save(){ $this->objSaver->save($this->messageObj); } }

As shown above, this completely new “BridgeObjectSaver” class is capable of storing an object of type “Message” in different places, such as a plain text file, an array or a simple cookie. Nevertheless, I’d like you to study specifically how all these tasks are performed by the mentioned bridge class.

As you can see, there’s a third object involved in this process called “ObjectSaver.” This object actually carries out all the storage procedures that I discussed before. Obviously the “BridgeObjectSaver” class behaves like a real “bridge” for “ObjectSaver” (hence the name of the pattern). At the same time, it fits the requirements of the bridge pattern, since its respective definition and implementation reside on different class hierarchies. Isn’t this great? Of course it is!

After examining the definition for the previous bridge class, surely you’ll think that creating these kinds of structures with PHP 5 is actually a straightforward process, therefore let’s move on and learn together how to build the corresponding object saver classes that were defined before.

To see how these classes will be properly created, please click on the link below and keep reading.

{mospagebreak title=Implementing the logic of a bridge class in a different hierarchy level}

In accordance with the concepts that you learned in the previous section, the “BridgeObjectSaver” class uses others to save target objects either to text files, cookies or arrays. Having at our disposal this handy programmatic structure, the logic that drives the bridge pattern is now easy to follow.

As I stated before, the “BridgeObjectSaver” class resides on a different hierarchy level, since its logic is implemented by other objects, in this case called “ObjectToArray,” “ObjectToFile” and “ObjectToCookie” respectively. Now, do you realize how the pattern in question works? I bet you do!

All right, having explained how the previous bridge class does its business, I’d like you to focus your attention on the signature for the following “bridged” classes that were discussed before. They’re defined as follows:

//define 'ObjectToArraySaver' class class ObjectToArraySaver{ private $targetArray=array(); // implement concretely the logic of 'save()' method public function save($messageObj){ $this->targetArray['messageobj']=$messageObj; } } // define 'ObjectToFileSaver' class class ObjectToFileSaver{ private $targetFile='default_file.txt'; // implement concretely the logic of 'save()' method public function save($messageObj){ if(!$fp=fopen($this->targetFile,'w')){ throw new Exception('Error opening target
file');               } if(!fwrite($fp,serialize($messageObj))){ throw new Exception('Error writing data to
target file');      } fclose($fp); } } // define 'ObjectToCookieSaver' class class ObjectToCookieSaver{ private $targetCookie='targetCookie'; // implement concretely the logic of 'save()' method public function save($messageObj){ setcookie($this->targetCookie,serialize($messageObj),
time()+7200); } }

As you can see, the three classes shown above now implement concretely the logic defined by “BridgeObjectSaver.” In this case in particular, each one of the previous classes exposes a “save()” method to save target objects to different locations, including text files, arrays and cookies. Quite handy, right?

Okay, at this point I’m quite sure that you grasped correctly the approach used for implementing the bridge pattern with PHP 5. After all, the process is reduced only to defining a few “bridged” classes that perform the tasks defined inside the corresponding bridge.

Now, let’s move forward and see together how all the previous classes can be put to work conjunctly to demonstrate the real capacity offered by the bridge design pattern. Therefore, go ahead and read the final section of the article. I’ll be there, waiting for you.

{mospagebreak title=Seeing the bridge pattern in action}

Logically, the best way to understand how the bridge pattern works rests on setting up an example where all the classes that were created previously are used together in the same script. In accordance with this, below I coded a few simple snippets which show how the bridge class saves a target object first to an array, then a text file, and finally a cookie. Thus, take a look at the list of try-catch blocks shown below:

try{ // instantiate 'Message' object $msg=new Message('This a test string that will be saved later
on'); // instantiate 'BridgeObjectSaver' object, and indicate that
target object will be saved to array $bObjSaver=new BridgeObjectSaver($msg,'array'); // save target object to array $bObjSaver->save(); } catch(Exception $e){ echo $e->getMessage(); exit(); }           try{ // instantiate 'Message' object $msg=new Message('This a test string that will be saved later
on'); // instantiate 'BridgeObjectSaver' object, and indicate that target object will be saved to file             $bObjSaver=new BridgeObjectSaver($msg,'file');             // save target object to text file             $bObjSaver->save(); } catch(Exception $e){ echo $e->getMessage(); exit(); } try{ // instantiate 'Message' object $msg=new Message('This a test string that will be saved later
on'); // instantiate 'BridgeObjectSaver' object, and indicate that
target object will be saved to a cookie $bObjSaver=new BridgeObjectSaver($msg,'cookie'); // save target object to a cookie $bObjSaver->save(); } catch(Exception $e){ echo $e->getMessage(); exit(); }

As you’ll realize, the above examples demonstrate a clear implementation of the bridge pattern with PHP 5. Of course, if you’re interested in learning more on this pattern, feel free to modify the original source code that I showed here, and experiment with developing more complex examples.


In this first part of the series, I introduced the core concepts of the bridge design pattern in PHP 5. As you hopefully learned, this pattern allows you to separate a given class from its corresponding implementation, without using abstract classes.

In the next part, I’m going to show you how to apply this pattern to create different data validation classes. The experience is really promising, therefore you don’t have any excuses to miss it!

Google+ Comments

Google+ Comments