The Basics of Implementing Adapter Objects with PHP

You may have already encountered situations in coding PHP applications in which you would like to use inheritance, but could not for one reason or another. Fortunately, there is an alternative for these situations that can help you achieve the same result. In this first article in a two-part series, you’ll learn about the adapter pattern.

Introduction

During your life as PHP developer, I’m quite sure you’ve been working with classes and objects for a while. That’s very convenient for those times when you need to create a well-defined relationship between these classes, constructing web applications that are highly maintainable from the very beginning.

In addition to mastering the main pillars of the object-oriented programming paradigm, like inheritance and polymorphism, probably you have already started implementing some kind of advanced interaction across several objects that goes beyond the boundaries of deriving a few subclasses from the corresponding parent class.

Actually, while all this sounds good and seems to satisfy the most common requirements that must eventually be tackled when developing a certain PHP application, the truth is that sometimes using inheritance for creating specific objects inside a program isn’t convenient. This could be because all the pertinent base classes weren’t initially defined with a future expansion of their functionality in mind, or just because of simple ignorance.

In either case, there must be an alternative way to extend the functionality of a base class without directly using inheritance. Also, at the same time, this approach has to be flexible enough to allow extending this parent class in such a way that a newly-created object can fit the particular requirements of another one. Does this sound a bit confusing? Fear not, because the topic is really understandable.

To put things in a simpler way, say you have two predefined classes, where the first one must suit the demands of a second one, but as I said before, inheritance isn’t the most viable method for performing the corresponding coupling of classes. Now, after reading the above lines, you should be asking yourself: how can this be done?

Fortunately for you and me, there’s a straightforward method for tackling the problem. It consists of creating what is called an “adapter” class. As you’ll see later on in this article, this adapting class will take the original one and modify –and eventually expand — one or many of its methods to meet the specifications imposed by the destination class, all without appealing to the advantages of inheritance.

In crude terms, this method is known popularly as the “adapter” pattern, and during this two-part series, I’ll be taking an in-depth look at it. In this way, you’ll learn how to apply it within your own PHP applications and scripts.

The subject is really interesting, thus let’s no waste more time in preliminaries and start learning more on how to create adapter objects with PHP. Let’s do it together!

{mospagebreak title=The basics of adapter objects}

As you read in the introduction of this article, adapter objects can be useful for modifying the original structure of a specified class, but in this case without having to use inheritance to perform the corresponding structural changes.

Once the initial class have been altered via the mentioned adapter, an instance of it is usually passed in to another class, which expects the inputted object to conform the characteristics of a predefined model.

Of course, all this theory sounds interesting, but I’m sure that you want to see how the respective concepts can be translated into some pieces of functional PHP code. Therefore, my next step will be to set up a concrete example, where you can understand with minor hassles how an adapter class can be properly created.

First I’ll start developing the referenced example by coding the basic structure of a directory processor class with PHP 5. Then I’ll create a simple adapter class to illustrate the complete procedure, aimed at “adapting” the signature of the mentioned directory processor.

Having said that, here is the definition for the new “AbstractDirectoryProcessor” class. As its name indicates, it defines the generic model of a directory handling object. Please look at the following class:

//define abstract 'AbstractDirectoryProcessor' class abstractclass AbstractDirectoryProcessor{ private $dirPath; abstract public function fetchDirContent(); abstract public function getDirInfo(); }

As illustrated in the above example, the initial definition that corresponds to the “AbstractDirectoryProcessor” class outlines the generic interface that will be implemented by all the eventual child classes derived from it.

In this particular case, two abstract methods called “fetchDirContent()” and “getDirInfo()” respectively have been appropriately declared, which suggest clearly what type of tasks will be performed by the eventual subclasses, once the respective methods have been concretely implemented.

As you might have guessed, the first method will be used for retrieving the contents of a given directory, while the second one will be tasked with displaying some useful information about the directory in question. This is quite simple, isn’t it?

Now that you learned how the previous “AbstractDirectoryProcessor” class was defined, it’s time to see how a concrete directory handling class can be created, based upon the structure of the corresponding parent class that you saw before.

That’s exactly the topic that will be treated in the following section, therefore click on the link that appears below and keep reading.

{mospagebreak title=Defining a concrete directory processor class}

As I expressed in the section that you just read, the next step involved in the creation of an adapter class consists of defining a concrete directory processor which will implement all the abstract methods that were defined in the respective base class. Sounds logical, right?

Okay, having explained that, below I defined the structure of the brand-new “DirectoryProcessor” class that I mentioned before. Please take a look:

// define concrete 'DirectoryProcessor' class class DirectoryProcessor extends AbstractDirectoryProcessor{ //define constructor           public function __construct($dirPath){                 if(!is_dir($dirPath)){                         throw new Exception('Invalid directory path!'); }                   $this->dirPath=$dirPath;           }          // implement concretely 'fetchDirContent()' method             public function fetchDirContent(){                     if(!$dp=opendir($this->dirPath)){                     throw new Exception('Error opening selected
directory!');                   }                    $dircont='';                    while($file=readdir($dp)){                            $dircont.=$file.'<br />';                     }                     fclose($dp);                    // return directory contents                   return $dircont;            }             // implement concretely 'getDirInfo()' method             public function getDirInfo(){                     $pathinfo=pathinfo($this->dirPath);                    return 'Name of selected directory is
'.$pathinfo['dirname'].' and its base name is the following:  '.$pathinfo['basename'];

      } }

 

As you can see, the above defined “DirectoryProcessor” class simply implements in a concrete way all the methods that were originally declared abstract in the corresponding base class. In addition, the specific methods exposed by this new class perform some simple tasks, like fetching the content of a specified directory, which is directly inputted via the constructor, as well obtaining its name and path.

So far, I have at disposal a fully-functional directory handling class, which can be basically used as indicated below:

try{ // instantiate 'DirectoryProcessor' object        $dirProc=new DirectoryProcessor('default_path/');         // display contents of directory         echo '<h2>Contents of selected directory are as follows:</h2>'; echo $dirProc->fetchDirContent();            // display information on selected directory         echo '<h2>Information on selected directory is as follows:</h2>'; echo $dirProc->getDirInfo(); } catch(Exception $e){         echo $e->getMessage();         exit(); } /* displays the following: Contents of selected directory are as follows: . .. file1.txt file2.txt Information on selected directory is as follows: Name of selected directory is . and its basename is the following:
default_path */

In this case, provided that the sample “default_path” directory above specified contains the files “file1.txt” and “file2.txt” respectively, the output generated by the previous script corresponds to a logical expectation.

However, there are two important things worth noticing about the previous example. Obviously, the first one rests on the fact that the same functionality could have been achieved using the “DirectoryIterator” class that comes with PHP 5, while the second one is even more relevant for this article in particular, since there’s still not a clue of how to create an adapter class.

Well, let me answer these questions in the correct order: definitely I could have used the neat “DirectoryIterator” class bundled with the SPL package to work with a highly standard directory handling class, but you shouldn’t worry about this for the moment, since this procedure will be covered in the following article of this series.

And finally, with reference to the second question, here is where things get really interesting!

Suppose that for whatever reason, you need to expand the functionality of the previous “DirectoryProcessor” class, but without using the goodies of inheritance, in addition to giving the class a predefined structure. How can this be done? This issue can be easily tackled by creating an adapter class that performs the mentioned expansion!

Want to learn how this adapter class will be defined? Go ahead and visit the following section. I’ll be there, waiting for you.

{mospagebreak title=Seeing the adapter pattern in action}

As discussed in the previous section, one of the easiest ways to extend the functionality of a given class without having to use inheritance is simply by defining an adapter class. The adapter class will modify one or more methods of the original one to conform a specific model.

This being said, and based upon all the prior sample classes, here is the complete process for creating the aforementioned adapter class. Take a look, please:

// define abstract 'DirectoryProcessorAdapter' class abstract class AbstractDirectoryProcessorAdapter{       private $dirProcessor;       abstract public function getDetailedDirInfo(); } // define concrete 'DirectoryProcessorAdapter' class class DirectoryProcessorAdapter extends AbstractDirectoryProcessorAdapter{             // define constructor             public function __construct(DirectoryProcessor $dirProcessor){                         $this->dirProcessor=$dirProcessor;             }             // implements concretely 'fetchDetailedDirContent()' method             public function getDetailedDirInfo(){                         return '<h1>Detailed information about selected
directory is as follows:</h1><h2>Contents of selected directory is as follows:</h2>'.$this->dirProcessor->
fetchDirContent().'<h2>Data about selected directory is as follows:</h2>'.$this->dirProcessor->getDirInfo();             } }

As you can see, the above defined “DirectoryProcessorAdapter” class is now capable of extending the functionality of the previous “DirectoryProcessor” by simply injecting this object into the corresponding constructor, and finally defining the completely new “fetchDetailedDirContent()” method.

Here, it’s clear to see that this method combines the capacity of “fetchDirContent()” and “getDirInfo()” in one single block and displays the respective information on the browser. See how an adapter class now fits into the whole picture?

Now that you hopefully grasped the logic that drives the “DirectoryProcessorAdapter” class that you learned before, I’d like to go one step forward and show you how to properly use this class. Therefore, examine the example listed below, which demonstrates a simple implementation of the adapter class:

try{ // instantiate 'DirectoryProcessor' object         $dirProc=new DirectoryProcessor('default_path/');         // instantiate 'DirectoryProcessorAdapter' object         $dirProcAdapter=new DirectoryProcessorAdapter($dirProc); // display detailed information on selected director
(implements the adapter pattern)         echo $dirProcAdapter->getDetailedDirInfo(); } catch(Exception $e){     echo $e->getMessage();     exit(); } /* displays the following: Detailed information about selected directory is as follows: Contents of selected directory is as follows: . .. file1.txt file2.txt Data about selected directory is as follows: Name of selected directory is . and its basename is the following:
default_path */

As you’ll realize, the previous example demonstrates how easy it is to use the adapter class that I defined a few lines above. After a new directory processor object and its respective adapter have been instantiated, the “getDetailedDirInfo()” method is called up at the end of the script, which neatly displays the directory information detailed above. 

After all, implementing the adapter pattern with PHP 5 isn’t difficult. As you saw in the previous example, a given class can be easily modified without using inheritance, in cases where this approach is not viable.

To wrap up

We’ve come to the end of this first article. Hopefully, after learning all the concepts and examples given here, you’ll have a clearer idea of how to create an adapter class with PHP.

But this educational journey hasn’t ended yet, since in the second (and last) tutorial you’ll learn how to create an adapter that works in tandem with the standard “DirectoryIterator” class, included with PHP 5, in addition to building adapters for MySQL. Therefore, meet you in the last part!

Google+ Comments

Google+ Comments