Introduction
Let’s take a look at one of the popular design patterns in PHP - Adapter Pattern, and see why we need it in our PHP development.
What is Adapter Pattern?
What is an adapter? Well in daily life, an adapter is just an object that you use to connect two different pieces of electrical equipment, or to connect two pieces of equipment to the same power supply. For example, your friend just bought you a trendy widget from overseas, but the widget uses 220V power, and in your country it’s 110V power. At this moment, you need an adapter, a device that can transform 220V to 110V. The Adapter design pattern actually plays the same role in Object-Oriented Programming - it is used to transform a date format or data type that does not fit to your system to the one that fits.
For example, our Server side has a class named Weather
, and its static
function named showWeather()
displays weather information:
class Weather {
public static function showWeather() {
$todayWeather = array('temperature' => 28, 'wind' => 7, 'condition' => 'Sunny');
return serialize($todayWeather);
}
}
There’s a static
method showWeather()
within this class, and it returns a PHP string
containing the information of today’s weather. The serialize()
function turns the array into a string
.
And here is the Client side code:
$weather = unserialize(Weather::showWeather());
echo 'Temperature: ', $weather['temperature'], '<br>';
echo 'Wind: ', $weather['wind'], '<br>';
echo 'Condition: ', $weather['condition'], '<br>';
When running the script, it displays:
Temperature: 28
Wind: 7
Condition: Sunny
This works fine for the client side, as both server side and client side are PHP code.
But now there are a bunch of mobile apps also needing to call the showWeather()
method, and these apps are written in Java or Objective-C. Obviously, the Java clients don’t ‘understand’ the serialized PHP string
that showWeather()
returns. Now what? Can we change the server side code from PHP to Java? Of course not, because if doing so, the original PHP client will be impacted (not working properly anymore). The solution is, we need an ‘adapter’ to do some transformation.
Adapter Pattern’s Usage
In this scenario, we don’t want to change the code within Weather
class, as that will be a bad practice. Remember Bertrand Meyer’s famous quote: “Software entities should be open for extension, but closed for modification”? So we will add a new Class named AdapterWeather
and it inherits the Weather
class:
class AdapterWeather extends Weather {
public static function showWeather() {
$todayWeather = parent::showWeather();
$todayWeather = unserialize($todayWeather);
$todayWeather = json_encode($todayWeather);
return $todayWeather;
}
}
Within this subclass, we define another showWeather()
method, it does the following things:
- Call parent class’s
showWeather()
to get the weather string
, and then unserialize it; - Encode the unserialized
string
to JSON format. The purpose is to convert the PHP string
to a universal data format that each programming language can understand. It’s usually JSON or XML. Now you see the ‘transformation’ part of the adapter, just like a real adapter that can convert 220V power to 110V, right?
Now the client side code:
$weather = unserialize(Weather::showWeather());
echo 'Temperature: ', $weather['temperature'], '<br>';
echo 'Wind: ', $weather['wind'], '<br>';
echo 'Condition: ', $weather['condition'], '<br>';
$weather = AdapterWeather::showWeather();
$weather = json_decode($weather);
echo 'Temperature: ', $weather->temperature, '<br>';
echo 'Wind: ', $weather->wind, '<br>';
echo 'Condition: ', $weather->condition, '<br>';
The output is as follows:
Temperature: 28
Wind: 7
Condition: Sunny
Temperature: 28
Wind: 7
Condition: Sunny
Please note that we haven’t changed the original Weather
class code, so the original PHP client won’t be affected (still the same code); we just add an adapter class and it simply get the ‘old’ data and transforms it to ‘new’ data. The new client (be it Java or Objective-C or Python) now can just call the Adapter’s showWeather()
method and decodes the JSON data. Then it can display the weather information in its own way (Here, I didn’t create a Java or OC snippet but still use PHP code for simplicity, but you got the picture and this is how it works.)
Summary
Adapter Pattern is a relatively simple but very practical pattern. I am writing a series of articles on PHP design patterns, and if you are interested, please check some of my other articles on CodeProject.