

Download the source for the Adapter Pattern.
Have two classes that need to work together but have different interfaces? Often referred to as the wrapper pattern, or simply a wrapper, the adapter pattern can translate one interface for a class into a compatible interface by providing its interface to clients while using the original interface. The adapter translates calls to its interface into calls to the original interface, and the amount of code necessary to do this is typically small.
For example, John the florist has a program that will identify different kinds of roses and how they smell. His interface looks strikingly similar to Rose.interface.php:
interface Rose {
public function identify();
public function smell();
}
Using his rose interface, John has produced a few classes representing some of the different type of roses he sells. Here is RedRose.class.php:
require_once("Rose.interface.php");
class RedRose implements Rose {
private $name;
public function __construct() {
$this->name = "Red ";
}
public function identify() {
echo $this->name . "Rose";
}
public function smell() {
echo "sweet";
}
}
With all of his flowers using the same interface, John’s program hums along smoothly, identifying the name and smell of any rose he sells. But John would like to add s new type of flower the selection of his shop.
John’s new flowers arrive, a species called the Dutchman’s Pipe, and it is one of the most horrendous smelling blossoms he has ever encountered. Not only did it come with a deathly smell, here is the interface that was included, DutchmansPipe.interface.php:
interface DutchmansPipe {
public function run();
public function stink();
}
John can barely get close enough to tell which kind of Dutchman’s Pipe it is but from the invoice he determines it’s from Brazil and cobbles together BrazilianDutchmansPipe.class.php:
require_once("DutchmansPipe.interface.php");
class BrazilianDutchmansPipe implements DutchmansPipe {
private $name;
public function __construct() {
$this->name = "DutchmansPipe";
}
public function run() {
echo $this->name;
}
public function stink() {
echo "like death";
}
}
Right away, John can tell he is going to have problems with this flower… and getting it to work with his old software is the least of his headaches, after all, John is an adaptive person…
Looking at the two interfaces, John sees that they are very similar and figures he could adapt the new flower to fit his existing program. To do this he creates a class to serve as the adapter by implementing the Rose interface in a slightly different manner. Here is DutchmansPipeAdapter.class.php:
require_once("Rose.interface.php");
class DutchmansPipeAdapter implements Rose {
private $_dutchmansPipe;
public function __construct($dp) {
$this->_dutchmansPipe = $dp;
}
public function identify() {
$this->_dutchmansPipe->run();
}
public function smell() {
$this->_dutchmansPipe->stink();
}
}
With the methods of one interface being called by the methods from the original interface, John should be able to feed these new flowers into his program with no problem…
Let’s go ahead and give this a whirl, we’ll create a DutchmansPipe to store our flower and then feed it into the adapter and see what happens. Here is index.php:
function __autoload($class_name) {
require_once 'classes/' . $class_name . '.class.php';
}
function checkFlower($flower) {
echo "Name: ";
$flower->identify();
echo "<br/>Odor: ";
$flower->smell();
echo "<br/>";
}
$dutchmansPipe = new BrazilianDutchmansPipe();
echo "A DutchmansPipe:<br/>Name: ";
$dutchmansPipe->run();
echo "<br/>Odor: ";
$dutchmansPipe->stink();
echo "<br/><br/>";
echo "A Rose:<br/>";
checkFlower(new RedRose());
checkFlower(new YellowRose());
echo "<br/>";
$adapter = new DutchmansPipeAdapter($dutchmansPipe);
echo "A Rose by any other name:<br/>";
checkFlower($adapter);
You should get something like:
A DutchmansPipe:
Name: DutchmansPipe
Odor: like death
A Rose:
Name: Red Rose
Odor: sweet
Name: Yellow Rose
Odor: sweet
A Rose by any other name:
Name: DutchmansPipe
Odor: like death
Besides making it possible for two interfaces to, uh, interface, the adapter pattern is also responsible for transforming data into appropriate forms. For instance, if multiple boolean values are stored as a single integer but your consumer requires a 'true'/'false', the adapter would be responsible for extracting the appropriate values from the integer value. Use it wisely.
Download the source for the Adapter Pattern.