Design Patterns: The Adapter Pattern

In the last article, we looked at how the facade design pattern can be employed to simplify the employment of any large and complex system using only a simple facade class. 

In this article, we will continue our discussion on design patterns by taking a look at the adapter design pattern. This particular pattern can be used when your code is dependent on some external API, or any other class that is prone to change frequently. This pattern falls under the category of "structural patterns" because it teaches us how our code and our classes should be structured in order to manage and/or extend them easily.

Again, I'd like to reiterate that design patterns have nothing new over traditional classes. Instead, they show us a better way to structure our classes, handle their behavior, and manage their creation.

The Problem

In the above code, you can see that we are utilizing a PayPal class to simply pay the amount. Here, we are directly creating the object of the PayPal class and paying via PayPal. You have this code scattered in multiple places. So we can see that the code is using the $paypal->sendPayment('amount here'); method to pay. 

Some time ago, PayPal changed the API method name from sendPayment to payAmount. This should clearly indicate a problem for those of us who have been using the sendPayment method. Specifically, we need to change all sendPayment method calls to payAmount. Imagine the amount of code we need to change and the time we need to spend on testing each of the features once again.

The Solution

One solution to this problem is to use the adapter design pattern. 

According to Wikipedia:

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.

In this case, we should create one wrapper interface which makes this possible. We will not make any changes in the external class library because we do not have control over it and it may change any time. 

Let's dig into the code now, which shows the adapter pattern in action:

Study the code above and you should be able to tell that we have not introduced any changes into the main PayPal class. Instead we have created one interface for our payment adapter and one adapter class for PayPal.

And so afterward we have made the object of the adapter class instead of the main PayPal class. While creating an object of adapter class we will pass the object of the main PayPal class as an argument, so that adapter class can have a reference to the main class and it can call the required methods of the main PayPal class.

Let's find out how we can utilize this method directly:

Now imagine PayPal changes its method name from sendPayment to payAmount. Then we just need to make changes in paypalAdapter. Just have a look at the revised adapter code, which has just one change.

So just one change and we are there.

Adding a New Adapter

At this point, we've seen how we can use the adapter design patten to overcome the aforementioned scenarios. Now, it's very easy to add a new class dependent on the existing adapter. Let's say the MoneyBooker API is there for payment.

Then instead of using the MoneyBooker class directly, we should be applying the same adapter pattern we just used for PayPal.

As you can see, the same principles apply. You define a method that's available to third-party classes and then, if a dependency changes its API, you simply change the dependent class without exposing its external interface.

Conclusion

A great application is constantly hooked into other libraries and APIs, so I would propose that we implement the adapter method, so that we do not experience any trouble when a third-party API or library changes its code base.

I have tried my best to provide an elementary and yet useful example to demonstrate the adapter design pattern, but if you have additional comments or questions, please don't hesitate to add them in the feed below.

Tags:

Comments

Related Articles