Talking to External Services Easily With The PHP Adapter Pattern

Have you interacted before with remote api or third party library. Of course most of us dealt with external Apis to accomplish some tasks.

The problem arises when these external Apis gets new updates from time to time so we need a way to keep track of these updated so that our application gets continue running without drop or crash.

 

To deal with this kind of problems we use the so called Adapter Pattern.

In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface

In this tutorial i will describe the Adapter Pattern In PHP so let’s see a real world example of this pattern.

Let’s imagine that you interacted before with facebook Sdk you notice that there is a method that allows you to post to facebook wall like this:

class Facebook{
    public function post($msg)
    {
        // this will $msg to facebook
    }
}

// Client code
$facebook = new Facebook;
$facebook->post("This is for demonstration");

Now imagine that update facebook sdk library and the method named post() was changed to some other names like for example postToWall(). because the client code interacts directly with the facebook class and uses the method post() it will crash.

To overcome this problem we will create an interface that will act as a link between the facebook class and the client code as shown below:

class Facebook{
    public function postToWall($msg)
    {
        // this will post a message into facebook wall
    }
}

interface socialMediaAdapter{
    public function post($msg);
}

class FacebookAdapter implements socialMediaAdapter{
    private $facebook;
    
    public function __construct(Facebook $facebook) {
        $this->facebook = $facebook;
    }
    
    public function post($msg) {
        $this->facebook->postToWall($msg);
    }
}

$facebook = new FacebookAdapter(new Facebook());
$facebook->post("Posting message...");

So as shown above we created a new interface called socialMediaAdapter and also added a new class FacebookAdapter. Now the client developer will no longer deal with the concrete facebook class instead it will deal with the FacebookAdapter. Also Note that if the facebook class updated for some season it will only need to be updated in the adapter class only and client code still working without any problems.

 

Another example of this pattern when you need to implement a payment method in an e commerce website. So you need to integrate paypal, Stripe, and 2checkout. Let’s see this in action:

// Concrete Implementation of PayPal Class
class PayPal {
     
    public function __construct() {
        // Your Code here //
    }
     
    public function sendPayment($amount) {
        // Paying via Paypal //
        echo "Paying via PayPal: ". $amount;
    }
}

interface PaymentAdapter 
{
	public function pay($amount);
}

class PaypalAdapter implements PaymentAdapter
{
	private $paypal;

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

	public function pay($amount)
	{
		$this->paypal->sendPayment($amount);
	}
}

// Client code
$paypal = new PaypalAdapter(new Paypal());
$paypal->pay(2345);

In the above code we created a concrete implementation of the paypal class. Then we created a new interface PaymentAdapter. Each adapter class needs to implement this interface. Now the client code can do a payment using the adapter and inject the Paypal class as shown:

// Client code
$paypal = new PaypalAdapter(new Paypal());
$paypal->pay(2345);

 

In the same way if you need to add a new payment methods for Stripe and 2Checkout just add a new adapter class like this:

class StripeAdapter implements MoneyBooker
{
	private $stripe;

	public function __construct(Stripe $stripe)
	{
		$this->stripe = $stripe;
	}

	public function pay($amount)
	{
		$this->stripe->doPayment($amount);
	}
}

// client code
$stripe = new StripeAdapter(new Stripe());
$stripe->pay(4492);

class TwoCheckoutAdapter implements MoneyBooker
{
	private $twoCheckout;

	public function __construct(TwoCheckout $twoCheckout)
	{
		$this->twoCheckout = $twoCheckout;
	}

	public function pay($amount)
	{
		$this->twoCheckout->doPayment($amount);
	}
}

// client code
$payment = new TwoCheckoutAdapter(new TwoCheckout());
$payment->pay(4492);

Conclusion

In this tutorial saw what is the Adapter pattern and how it can be applied. We also looked at some real world examples of this pattern. Always try to make use such pattern as it makes your code more flexible and maintainable. 

 

0 0 vote
Article Rating
Share this: