Adapter pattern PHP

Imagine you are working on a large code base that depends on third-party SDK. For this context, we will take a library that manipulates images. A few days before going live, the SDK released a new update and now you have to go through your code base and update the relevant signature. This is not an ideal solution.

The Adapter pattern helps us to cope with new or additional changes.

For example your team member has written a class ContactReader and ContactSaver

The functionality is simple. ContactReader reads data from an API and ContactSaver saves the data into the database.

class ContactReader = reads the contact from api
class ContactSaver = saves the contacts into database

 

class ContactReader 
{
    /**
      @var array Contacts
    */
    public $contacts;
    /**
    Loads contacts
    **/
    public function contacts()
    {
 
       $this->contacts = // fetch contact from API
       return $this;
          
    }
}
class ContactSaver
{
    /**
     Saves contact
     @param  Contacts
    **/
    public function saveContact($contact)
    {
              //saves the contact into database
    }    
}

This is how the classes are being used.

$objContactReader = new ContactReader();
$contacts = $objContactReader->contacts();

$objContactSaver = new ContactSaver();
$objContactSaver->saveContact($contacts);

From the above, we can conclude that class ContactReader returns an instance of itself with the contacts, ContactSaver method saveContact accepts the contacts and saves it into the database.

However, a new requirement is requested to modify the data prior to saving it to the database.
Such requirement is not provided by your team member class. We will use the adopter pattern to provide this new feature and at the same time maintain the team members class functionality.

Our Adapter class will extend ContactSave, which inherits its functionality and modify the contacts providing the new feature.

ContactSaverAdapter

class ContactSaverAdapter extends ContactSaver
{
   /**
    Save contacts
    @var Contacts
   **/
   public function saveContact($contacts)
   {
      // our code to modify the data 
     // 
      parent::saveContact($contacts);
   }
}

Our main class process will change to:

$objContactReader = new ContactReader();
$contacts = $objContactReader->contacts();
// we create an instance of adapter this time
$objContactSaver = new ContactSaverAdapter();
$objContactSaver->saveContact($contacts);

In the Adapter pattern we should always ensure that all of the operations of ContactSaver remain, The Adapter pattern provides extra functionality over the old class. The Adapter pattern might seem time-consuming but in the long run, it saves time.

It is best practice to write an Adapter for any API you use, as it might change anytime.