ADAPTER PATTERN

Sometimes, there could be a scenario when two objects don’t fit together, as they should in-order to get the work done. This situation could arise when we are trying to integrate a legacy code with a new code, or when changing a 3rd party API in the code. This is due to incompatible interfaces of the two objects which do not fit together.

In other words, Adapter design pattern is one of the structural design patterns and it’s used so that two unrelated interfaces can work together. The object that joins these unrelated interfaces is called an Adapter. As a real life example, we can think of a mobile charger as an adapter because mobile battery needs 3 volts to charge but the normal socket produces either 120V (US) or 240V (India). So the mobile charger works as an adapter between mobile charging socket and the wall socket.

In the adapter pattern, a wrapper class (i.e., the adapter) is used translate requests from it to another class (i.e., the adoptee). In effect, an adapter provides particular interactions with an adoptee that are not offered directly by the adoptee.

The adapter pattern takes two forms. In the first form, a “class adapter” utilizes inheritance. The class adapter extends the adoptee class and adds the desired methods to the adapter. These methods can be declared in an interface (i.e., the “target” interface).In the second form; an “object adapter” utilizes composition. The object adapter contains an adoptee and implements the target interface to interact with the adoptee.

Apple.java

package com.myjavablog.structural.adapter;

public class Apple {

public void getAppleColor(String color){
System.out.println("Apple color is "+ color);
}
}

Orange.java

package com.myjavablog.structural.adapter;

public class Orange {

public void getOrangeColor(String color){
System.out.println("Orange color is "+ color);
}
}

AppleAdapter.java adapter class –

package com.myjavablog.structural.adapter;

public class AppleAdapter extends Apple {

//Purpose of sample problem is to orange as Apple
private Orange orange;

public AppleAdapter(Orange orange) {
this.orange = orange;
}

public void getColor(String color){
orange.getOrangeColor(color);
}
}

AdaterPatternTest.java class –

package com.myjavablog.structural.adapter;

public class AdaterPatternTest {

public static void main(String[] args) {

Apple apple1 = new Apple();
apple1.getAppleColor("green");

Orange orange = new Orange();
AppleAdapter adapter = new AppleAdapter(orange);
adapter.getAppleColor("red");
}
}

 

Output:

Apple color is green
Apple color is red

Orange is adoptee, apple is target & AppleAdapter is the adapter. Here idea is to pass adoptee in adapter’s constructor to achieve the goal.

 

When to use Adapter Pattern:

The Adapter pattern should be used when:

  • There is an existing class, and its interface does not match the one you need.
  • You want to create a reusable class that cooperates with unrelated or unforeseen classes, that is, classes that don’t necessarily have compatible interfaces.
  • There are several existing subclasses to be use, but it’s impractical to adapt their interface by subclassing every one. An object adapter can adapt the interface of its parent class.

Adapter Pattern Example in JDK:

  • java.util.Arrays#asList()
  • java.io.InputStreamReader(InputStream) (returns a Reader)
  • java.io.OutputStreamWriter(OutputStream) (returns a Writer)
Bitnami