Adapter Pattern in PHP

Can we Adapt SMS into MAIL?
Now we’re going to do an impossible task.
Are you prepared?
Can we start?
This chapter is about the adapter pattern. It’s one of the design patterns that you’re currently on. Let us start with a real world example.
You know that internet connection is absolutely necessary for sending emails. Is it true in the real world? You’d say, well, I know that. An internet networking is a must.

Can we solve this problem by using some intermediary method? Situation may come where you go to a place where internet connection is not available at all. Or it’s very weak indeed to send an important mail.
What’s to be done in that situation?
There is a solution.
Adapter!
Yes, there we can choose IFTTT as the adapter. IFTTT is a service that supports automating tasks with popular API’s. Thus we can use IFTTT as the adapter to convert our SMS to MAIL.
What’s happening behind the scene is: IFTTT service communicates with the internet and just changes your SMS into MAIL. In a land with no internet connection cannot restrict you sending mails any more!
In essence this is all about adapter patterns in PHP.
An adapter, basically, helps two incompatible interfaces to work mutually. It sounds nice but the task is not so pleasant. The interfaces we’re talking about may seem to be incompatible but their inner functionality should match and work at tandem. Imagine a situation where the client expects an interface but at that moment you cannot supply that. You have a completely different interface. So you use an adapter and that adapter translates your interface into the client’s interface. So the client shouldn’t change her interface but actually gets a completely different interface through that adapter.
Your client expects a mail but at present you don’t have any internet connection. You have a mobile and you can send a SMS. But your SMS should have been translated into a MAIL by the time when it reaches the client.
You use IFTTT adapter and that service converts your SMS to MAIL.
Let us see how we can do that in our code.
First, you think about a simple ‘Mobile’ class that sends SMS and a “Person” class receives that SMS.

class Mobile {

public function sendMessage() {

var_dump("You have a new SMS.");

}

}

class Person {

public function recieve($message) {
$message->sendMessage();
}
}

$person = new Person();
echo $person->recieve(new Mobile());

The output is obvious. Now we can use an interface for lose coupling of our class object so that we can develop this code into this.

interface MobileInterface {
public function sendMessage();
}

class Mobile implements MobileInterface {

public function sendMessage() {

var_dump("You have a new SMS.");

}

}

class Person {

public function recieve(MobileInterface $message) {
$message->sendMessage();
}
}

$person = new Person();
echo $person->recieve(new Mobile());

The output remains same. It’s not changed. Now we’d like to have a ‘Mail’ class where we can send a mail. We’ve done the same thing through our ‘Mobile’ class. We also use another Mail interface for making our code loosely coupled. We also try an impossible task. We want that the person should get a mail through the mobile interface. Watch the last line carefully.


interface MobileInterface {
public function sendMessage();
}

interface MailInterface {
public function sendMail();
}

class Mobile implements MobileInterface {

public function sendMessage() {

var_dump("You have a new SMS.");

}

}

class Mail implements MailInterface {

public function sendMail() {

var_dump("You have a new MAIL.");

}

}

class Person {

public function recieve(MobileInterface $message) {
$message->sendMessage();
}
}

$person = new Person();
echo $person->recieve(new Mail());

What will be the output?
What you’re expecting is correct. It’ll give an error.

PHP Fatal error: Uncaught TypeError: Argument 1 passed to Person::recieve() must implement interface MobileInterface, instance of Mail given, called in /home/hagudu/Code/php7book1/Day4/adapter.php on line 41 and defined in /home/hagudu/Code/php7book1/Day4/adapter.php:35
Stack trace:
#0 /home/hagudu/Code/php7book1/Day4/adapter.php(41): Person->recieve(Object(Mail))
#1 {main}
thrown in /home/hagudu/Code/php7book1/Day4/adapter.php on line 35

You have no internet connection but you want that your SMS will be converted to MAIL and the person will receive that. It’s impossible.
You can make it possible only if you can use an adapter. An adapter, that’ll convert your SMS into MAIL.
To do that we write an adapter class that actually uses mobile interface to send SMS. And while doing that it will use ‘Mail’ class in its constructor so that mail object can convert your SMS into MAIL.
Watch the adapter class carefully.

class IFTTTadapter implements MobileInterface {

private $ifttt;

public function __construct(Mail $message) {
$this->ifttt = $message;
}

public function sendMessage() {
$this->ifttt->sendMail();
}
}

When the ‘IFTTTadapter’ class is in place, you can safely send SMS like this:

class Person {

public function recieve(MobileInterface $message) {
$message->sendMessage();
}
}

$person = new Person();
echo $person->recieve(new Mobile());

And it’ll give you an output like this:

string(8) "You have a new SMS."

But what happens when you use the IFTTTadapter? The whole bunch of code looks like this:


interface MobileInterface {
public function sendMessage();
}

interface MailInterface {
public function sendMail();
}

class IFTTTadapter implements MobileInterface {

private $ifttt;

public function __construct(Mail $message) {
$this->ifttt = $message;
}

public function sendMessage() {
$this->ifttt->sendMail();
}
}

class Mobile implements MobileInterface {

public function sendMessage() {

var_dump("You have a new SMS.");

}

}

class Mail implements MailInterface {

public function sendMail() {

var_dump("You have a new MAIL.");

}

}

class Person {

public function recieve(MobileInterface $message) {
$message->sendMessage();
}
}

$person = new Person();
echo $person->recieve(new IFTTTadapter(new Mail()));

The last part of the code is extremely important.

class Person {

public function recieve(MobileInterface $message) {
$message->sendMessage();
}
}

$person = new Person();
echo $person->recieve(new IFTTTadapter(new Mail()));

The person or client class remains unchanged. It sends message through ‘Mobile Interface’. And finally the person object or client receives it through IFTTTadapter class and Mail method. So the output comes out as expected.

string(8) "You have a new MAIL."

Finally we can conclude that adapter pattern works as a connection between two incompatible interfaces. It belongs to structural design pattern as this pattern converts one independent interface to act as another without inviting any trouble.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s