Have you ever experienced inconvenience of having a different type of socket for your electric plugs, like when you travel to a different country? If you don’t have an adapter, you will not be able to use that socket and power up your devices. It’s good that adapters are generally well available to purchase in the nearest CVS.
When we program an application, we often work with 3rd party libraries, various classes and objects. All of them inherit different classes, and functions that they are being passed to expect certain types of objects and will not accept just about anything. Imagine, you have a user system in an application. And in addition to users you also have a separate entity, like Subscribers who get registered in your system only using email and then being sent regular mails to. And now, what if we want to have a function that would enumerate all existing user-related entities. We want to be able to aggregate all users and subscribers in one list, and then do something with it, like get all email addresses for example. We will be able to do that just fine with User class, but we would encounter a problem when we get a Subscriber class. See, our aggregating function expects all of the objects that are passed to it to be of User class type. How can we solve this problem? With the use of the Adapter Pattern, of course!
The Adapter Pattern:
converts the interface of a class into another interface the client expects. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
What Adapter does is enables you to work with another class that expects different interface. You no longer need to change the code of the original class to make it work. Little change – big effect! Adapter acts as a middle party by receiving requests from the client and changing them into requests that that other class can understand. You can also see adapter as a translator between two parties: it acts as one type, accepts the request, translates it into an appropriate request to the other type, and passes it along.
Adapter implements a lot of great object-oriented principles:
- It decouples the client from the implemented interface.
- It uses object composition to wrap the adaptee with given interface.
- It binds client to interface, and not an implementation.
// Example in Java
// Source: https://en.wikipedia.org/wiki/Adapter_pattern
interface LightningPhone {
void recharge();
void useLightning();
}
interface MicroUsbPhone {
void recharge();
void useMicroUsb();
}
class Iphone implements LightningPhone {
private boolean connector;
@Override
public void useLightning() {
connector = true;
System.out.println("Lightning connected");
}
@Override
public void recharge() {
if (connector) {
System.out.println("Recharge started");
System.out.println("Recharge finished");
} else {
System.out.println("Connect Lightning first");
}
}
}
class Android implements MicroUsbPhone {
private boolean connector;
@Override
public void useMicroUsb() {
connector = true;
System.out.println("MicroUsb connected");
}
@Override
public void recharge() {
if (connector) {
System.out.println("Recharge started");
System.out.println("Recharge finished");
} else {
System.out.println("Connect MicroUsb first");
}
}
}
class LightningToMicroUsbAdapter implements MicroUsbPhone {
private final LightningPhone lightningPhone;
public LightningToMicroUsbAdapter(LightningPhone lightningPhone) {
this.lightningPhone = lightningPhone;
}
@Override
public void useMicroUsb() {
System.out.println("MicroUsb connected");
lightningPhone.useLightning();
}
@Override
public void recharge() {
lightningPhone.recharge();
}
}
public class AdapterDemo {
static void rechargeMicroUsbPhone(MicroUsbPhone phone) {
phone.useMicroUsb();
phone.recharge();
}
static void rechargeLightningPhone(LightningPhone phone) {
phone.useLightning();
phone.recharge();
}
public static void main(String[] args) {
Android android = new Android();
Iphone iPhone = new Iphone();
System.out.println("Recharging android with MicroUsb");
rechargeMicroUsbPhone(android);
System.out.println("Recharging iPhone with Lightning");
rechargeLightningPhone(iPhone);
System.out.println("Recharging iPhone with MicroUsb");
rechargeMicroUsbPhone(new LightningToMicroUsbAdapter(iPhone));
}
}
// Example in PHP
// Source: https://en.wikipedia.org/wiki/Adapter_pattern
interface IFormatIPhone
{
public function recharge();
public function useLightning();
}
interface IFormatAndroid
{
public function recharge();
public function useMicroUsb();
}
// Adaptee
class IPhone implements IFormatIPhone
{
private $connectorOk = FALSE;
public function useLightning()
{
$this->connectorOk = TRUE;
echo "Lightning connected -$\n";
}
public function recharge()
{
if($this->connectorOk)
{
echo "Recharge Started\n";
echo "Recharge 20%\n";
echo "Recharge 50%\n";
echo "Recharge 70%\n";
echo "Recharge Finished\n";
}
else
{
echo "Connect Lightning first\n";
}
}
}
// Adapter
class IPhoneAdapter implements IFormatAndroid
{
private $mobile;
public function __construct(IFormatIPhone $mobile)
{
$this->mobile = $mobile;
}
public function recharge()
{
$this->mobile->recharge();
}
public function useMicroUsb()
{
echo "MicroUsb connected -> ";
$this->mobile->useLightning();
}
}
class Android implements IFormatAndroid
{
private $connectorOk = FALSE;
public function useMicroUsb()
{
$this->connectorOk = TRUE;
echo "MicroUsb connected ->\n";
}
public function recharge()
{
if($this->connectorOk)
{
echo "Recharge Started\n";
echo "Recharge 20%\n";
echo "Recharge 50%\n";
echo "Recharge 70%\n";
echo "Recharge Finished\n";
}
else
{
echo "Connect MicroUsb first\n";
}
}
}
// client
class MicroUsbRecharger
{
private $phone;
private $phoneAdapter;
public function __construct()
{
echo "---Recharging iPhone with Generic Recharger---\n";
$this->phone = new IPhone();
$this->phoneAdapter = new IPhoneAdapter($this->phone);
$this->phoneAdapter->useMicroUsb();
$this->phoneAdapter->recharge();
echo "---iPhone Ready for use---\n\n";
}
}
$microUsbRecharger = new MicroUsbRecharger();
class IPhoneRecharger
{
private $phone;
public function __construct()
{
echo "---Recharging iPhone with iPhone Recharger---\n";
$this->phone = new IPhone();
$this->phone->useLightning();
$this->phone->recharge();
echo "---iPhone Ready for use---\n\n";
}
}
$iPhoneRecharger = new IPhoneRecharger();
class AndroidRecharger
{
private $phone;
public function __construct()
{
echo "---Recharging Android Phone with Generic Recharger---\n";
$this->phone = new Android();
$this->phone->useMicroUsb();
$this->phone->recharge();
echo "---Phone Ready for use---\n\n";
}
}
$androidRecharger = new AndroidRecharger();
There are two different types of Adapter possible: object adapters and class adapters. The Adapter we already covered is the object adapter. Class adapter is a little different. It might not be possible to implement it in some cases. It requires the use of multiple inheritance, and not all languages are capable of that. For example, Java and many other OO languages do not allow it. The only difference that class adapter has with object adapter is that in class adapters we subclass both, the Target and the Adaptee. There are pros and cons in using either one:
- Object Adapter uses composition, and thus can be used to adapt children classes as well. This keeps things flexible.
- Class Adapter can override the behavior of adaptee, because it uses inheritance instead of composition. This makes things efficient.

https://en.wikipedia.org/wiki/File:ObjectAdapter.png

https://en.wikipedia.org/wiki/File:ClassAdapter.png
No matter which kind of Adapter you are going to choose, this pattern can come useful in a lot of situations. You no longer need to change implementation of the initial class to make it compatible with the other one – just create an adapter. Choosing which type to roll with should be based on developer’s decision whether to pursue flexibility or keep things more efficient. Language of choice will definitely has its say as well.


One thought on “Adapter Pattern”