The development process of programming is similar to the human development, it goes from low to high. Object-oriented programming became quite popular. The programming pioneers have found common problems in object-oriented programming, and also found solutions to solve these problems with an optimal manner in the majority of the cases. This article will mention a design pattern that is commonly used in object-oriented programming; the Adapter Pattern.

 

WHAT IS AN ADAPTER PATTERN?

 

An Adapter is kind of popular in our daily life. We often encounter many types of adapters such as: power adapters (voltage converter), laptop adapters (laptop charger), memory card adapters, etc… Mainly, it’s an intermediate bridge that helps operate two objects together.

Well, when we talk about Adapter Pattern, we’re talking about almost the same thing. When you have objects but that they can’t be used with your built interface because it does not fit, the most appropriate solution would be to create a new interface for the object with an intermediate interface layer which is called “Adapter”. This class is only responsible for the interface switch, the methods which this class will have to use are the ones of the object it adapts.

 

COMPOSITION

  • Client: This is the class that will use your object (the object of which you want to convert the interface).
  • Adaptee: This is the class that the Client class wants to use but that has an interface mismatch.
  • Adapter: This is the intermediate, making the interface switch in order to connect Adaptee and Client.

 

PATTERN CLASSIFICATION

 

In Object-oriented programming, we have two important concepts that are parallel to each other;

  • Composition: A class (A) will become a component of an other class (B). Class (A) does not inherit the Class (B) but it has every possibility from Class (B).
  • Inheritance: A class will inherits from Base class and inherits all possibilities from Base class.

 

With these two concepts, we have two ways to install the adapter class: Object Adapter and Class Adapter. 

 

 adapter design

 

OBJECT ADAPTER

 

Object Adapter is helpful if you want to use a class that doesn’t have quite the exact methods you need and that you can’t change the original class. The adapter can take the methods that you can access in the original class and adapt them into the methods you need. Let’s see what that means with the following example:

 

We have a class Adaptee with the following structure:

 

<?php

class SimpleBank {

   private $name;

   private $balance;

   function __construct($name_in, $balance_in) {

       $this->name = $name_in;

       $this->balance  = $balance_in;

   }

   function getName() {

       return $this->name;

   }

   function getBalance() {

       return $this->balance;

   }

}

?>

Inside SimpleBank class, we have two methods to get the bank account name and the bank balance. In a situation where the Client wants a method to print out the information above but that you can’t touch the SimpleBank class, you need an Adapter class:

 

<?php

class BankAdapter {

   private $bank;

   function __construct(SimpleBank $bank_in) {

       $this->bank = $bank_in;

   }

   function getNameAndBalance() {

       return $this->bank->getName().‘ have balance: ‘.$this->book->getBalance();

   }

}

?>

Now you can get the bank account name and the bank balance by using the method from BankAdapter class:

 

<?php

$bank = new SimpleBank(Bank Account Name, 10,000$);

$bankAdapter = new BankAdapter($bank);

echo ‘BANK ACCOUNT NAME AND BALANCE’;

echo $bankAdapter->getNameAndBalance();

?>

 

And the output will be:

 

BANK ACCOUNT NAME AND BALANCE:

Bank Account Name have balance: 10,000$

 

CLASS ADAPTER

 

Class Pattern that allows the interface of an existing class to be used for another interface. It is often used to make existing classes work with others, without modifying their source code.

Another advantage of the Class Pattern is that it allows us to decouple our Client code from the Adaptee.

In our example, we will work with a saved information account class. We have simple class:

 

<?php

class InformationManager {

   public function saveInformation($type = , $data) {

       switch($type){

           case “email”:

               $information = new EmailService();

               $information->getTitle($this->_data[‘title’]);

               $information->getMessage($this->_data[‘message’]);

               $information->getEmail($this->_data[’email’]);

               $information->saveEmail();

               break;

           case “facebook”:

               $information = new FacebookService($data);

               $information->getFirstName($this->_data[‘first_name’]);

               $information->getLastName($this->_data[‘last_name’]);

               $information->getEmail($this->_data[’email’]);

               $information->saveFacebook();

               break;

           default:

               break;

       }

   }

}

?>

 

We can list the problems with the InformationManager class, which is:

  • The class knows too much about each information type implementation.
  • If any of the information class changes, we have to change our class code.

So, to solve the problems above, we can use the class adapter by creating an interface that those adapter class will implement.

We can start by creating an InformationInterface class:

 

<?php

interface InformationInterface {

   public function setData($data);

   public function saveInformation();

}

?>

 

After that, we create two adapter class and each of them will be implemented InformationInterface:

 

<?php

class EmailAdapter implements InformationInterface

{

   protected $_data;

   public function setData($data){

       $this->_data = $data;

   }

   public function saveInformation()

   {

       $emailClient = new EmailService();

       $emailClient->getTitle($this->_data[‘title’]);

       $emailClient->getMessage($this->_data[‘message’]);

       $emailClient->getEmail($this->_data[’email’]);

       $emailClient->saveEmail();

   }

}

class FacebookAdapter implements InformationInterface

{

   protected $_data;

   public function setData($data){

       $this->_data = $data;

   }

   public function saveInformation()

   {

       $facebookClient = new FacebookService();

       $facebookClient->getFirstName($this->_data[‘first_name’]);

       $facebookClient->getLastName($this->_data[‘last_name’]);

       $facebookClient->getEmail($this->_data[’email’]);

       $facebookClient->saveFacebook();

   }

}

?>

 

Based on the code above, we can now rewrite our InformationManager class in the following way:

 

<?php

class InformationManager {

   public function saveInformation($type = , $data)

   {

       switch($type){

           case “email”:

               $information = new EmailAdapter();

               break;

           case “facebook”:

               $information = new FacebookAdapter();

               break;

           default:

               return false;

               break;

       }

       $information->setData($data);

       $information->saveInformation();

   }

}

?>

 

As long as the information services implement the InformationInterface, the information manager doesn’t need to worry about the specifics of each implementation.

 

SUMMARY

 

The Adapter Pattern is extremely useful when combined with SOLID design principles and it helps developers to write a cleaner and more maintainable code.

This article is for developers who are accustomed to thinking object-oriented programming, as well as understanding the characteristics and properties of the object.