Project Technical Lead
Java design pattern: Adapter
Today we will take a look at the first Java design pattern from the structural patterns category – Adapter. Design patterns in this category deal with class structure such as inheritance and composition.
Read more – a series of design patterns:
- Design pattern Singleton
- Design pattern Builder
- Design pattern Prototype
- Design pattern Factory
- Design pattern Abstract factory
What is the Adapter design pattern?
Adapter is a design pattern that allows communication between two existing classes or interfaces that cannot communicate with each other due to incompatibility of their interfaces. The adapter allows these incompatible parts to work together by providing a mediated interface.
What problem does the Adapter design pattern solve?
Thus, the Adapter solves the problem of communication between incompatible parts of components by creating an intermediate layer between them and transferring calls between interfaces. Adapter is useful when we need to integrate existing code or classes with new code that expects a different interface. Instead of changing the code of existing classes, we can create an adapter that will mediate the communication.
This design pattern can also be found in Java when working with the so-called wrapper classes. Wrapper classes create object types from primitive data types by wrapping them in an adapter, which then implements the desired object type properties. This then has the effect that we can work with an instance of the class Integer, similar to how we would work with an ordinary variable of type int.
Example of Adapter implementation in Java
Now we will show how to implement the Adapter pattern in Java.
We use the Tvar interface to calculate the area of any shape.
Tvar.java
package designpatterns;
public interface Tvar {
public int vypocitajObsah(int x);
}
This interface is also used by the implementation of the Stvorec class.
Stvorec.java
package designpatterns;
// Aktuálna implementácia rozhrania Tvar
public class Stvorec implements Tvar {
@Override
public int vypocitajObsah(int x) {
return x * x;
}
}
We would also like to use an external implementation for calculating the content of the circle supplied by a third party, but this does not implement our Shape interface, which we cannot modify because it is already in use.
Kruh.java
package designpatterns;
// Implementácia triedy Kruh dodaná externe cez knižnicu
public class Kruh {
public double vypocitajObsahKruhu(int r) {
return 3.14 * r * r;
}
}
The solution is to adapt the Kruh implementation to our Tvar interface. So we need an adapter since the methods are incompatible.
KruhAdapter.java
package designpatterns;
public class KruhAdapter extends Kruh implements Tvar {
@Override
public int vypocitajObsah(int x) {
return (int) vypocitajObsahKruhu(x);
}
}
Main.java
Now we can use both the Stvorec and Kruh shapes (via the KruhAdapter) and call the area method on them.
import designpatterns.KruhAdapter;
import designpatterns.Stvorec;
import designpatterns.Tvar;
// Použitie vzoru adapter
public class Main {
public static void main(String[] args) {
Tvar kruh = new KruhAdapter();
System.out.println("Obsah kruhu: " + kruh.vypocitajObsah(4));
Tvar stvorec = new Stvorec();
System.out.println("Obsah štvorca: " + stvorec.vypocitajObsah(4));
}
}
The output of this example is:
Summary
Adapter design pattern is used in a situation where a class needs to have a different interface than the one it currently has. Adapter allows classes to collaborate that would otherwise not collaborate due to their different interfaces. Adapter can be classified into a class adapter and an object adapter depending on the implementation used.
We have prepared the files with the above example in the form of code that you can run directly in Java. Download the Java Adapter code here.