The Adapter Design Pattern

By Michael Williams, Published on 03/12/2016

In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used from another interface. It is often used to make existing classes work with others without modifying their source code. Wikipedia

<?php
class Paypal
{
public function processPayment($amount)
{
// Processes payment with Paypal
echo "Payment processed for $amount";
}
}

$paypal = new Paypal();
$paypal->processPayment(100);

In the above code, we are using a Paypal class to process a paypal. The processPayment method would of course have more functionality in it. For the purposes of this demonstration and giving a code example that can actually be ran. It will echo a message with the amount paid.

This code will work fine for now. Lets imagine a couple things. We are instantiating the Paypal class directly in several places within our application. Some time passes and in a future version of the API. Paypal decides to rename processPayment to submitPayment.

We could of course manually update each piece of code where the Paypal class is instantiated. There must be a better way though.

<?php
// Unmodified Paypal class
class Paypal
{
public function submitPayment($amount)
{
// Processes payment with Paypal
echo "Payment processed for $amount";
}
}

// Our new interface with process method
interface PaymentAdapter
{
public function process($amount);
}

// Our PaypalAdapter which implements PaymentAdapter
class PaypalAdapter implements PaymentAdapter
{
private $paypal;

public function __construct(
Paypal $paypal
)
{
$this->paypal = $paypal;
}

public function process($amount)
{
$this->paypal->submitPayment($amount);
}
}

// Code where we process the payment
$paypal = new PaypalAdapter(new PayPal());
$paypal->process(50);

Looking at our changes you can see that we have not altered the Paypal class.

Instead, we have created a PaymentAdapter interface with an empty process method. This method will be available in any class that implements our adapter.

We then create a PaypalAdapter which implements our PaymentAdapter. In our process method, we call the submitPayment method from the paypal class.

When the payment is processed we only call our process method.

The benefit to this approach is any changes to the Paypal API will only need to be adjusted within our adapter, rather than having to modify code in several places.