Adapter pattern
Definition
The Adapter pattern converts the interface of a class into another interface the clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.
Intent
Adapter is a structural design pattern that allows objects with incompatible interfaces to collaborate.

Real-World Analogy
When you travel from the US to Europe for the first time, you may get a surprise when trying to charge your laptop. The power plug and sockets standards are different in different countries. That’s why your US plug won’t fit a German socket. The problem can be solved by using a power plug adapter that has the American-style socket and the European-style plug.

Object adapters and Class adapters
To implement Class adapters, you need a language that supports multiple inheritance (like C++). It is not possible in Java. All the details we generally see when it comes to Adapters are for Object adapters.
Object adapter
This implementation uses the object composition principle: the adapter implements the interface of one object and wraps the other one. It can be implemented in all popular programming languages.

- The Client is a class that contains the existing business logic of the program.
- The Client Interface describes a protocol that other classes must follow to be able to collaborate with the client code.
- The Service is some useful class (usually 3rd-party or legacy). The client can’t use this class directly because it has an incompatible interface.
- The Adapter is a class that’s able to work with both the client and the service: it implements the client interface, while wrapping the service object. The adapter receives calls from the client via the adapter interface and translates them into calls to the wrapped service object in a format it can understand.
- The client code doesn’t get coupled to the concrete adapter class as long as it works with the adapter via the client interface. Thanks to this, you can introduce new types of adapters into the program without breaking the existing client code. This can be useful when the interface of the service class gets changed or replaced: you can just create a new adapter class without changing the client code.
Implementation
Duck interface
public interface Duck {
public void quack();
public void fly();
}
Class implementing Duck interface
public class MallardDuck implements Duck {
public void quack() {
System.out.println("Quack");
}
public void fly() {
System.out.println("I'm flying");
}
}
Turkey interface
public interface Turkey {
public void gobble();
public void fly();
}
Class implementing Duck interface
public class WildTurkey implements Turkey {
public void gobble() {
System.out.println("Gobble gobble");
}
public void fly() {
System.out.println("I'm flying a short distance");
}
}
Duck adapter for Turkey interface
public class DuckAdapter implements Turkey {
Duck duck;
Random rand;
public DuckAdapter(Duck duck) {
this.duck = duck;
rand = new Random();
}
public void gobble() {
duck.quack();
}
public void fly() {
if (rand.nextInt(5) == 0) {
duck.fly();
}
}
}
Turkey adapter for Duck interface
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
public void quack() {
turkey.gobble();
}
public void fly() {
for(int i=0; i < 5; i++) {
turkey.fly();
}
}
}
Test class for Duck adapter
public class TurkeyTestDrive {
public static void main(String[] args) {
MallardDuck duck = new MallardDuck();
Turkey duckAdapter = new DuckAdapter(duck);
for(int i=0;i<10;i++) {
System.out.println("The DuckAdapter says...");
duckAdapter.gobble();
duckAdapter.fly();
}
}
}
Test class for Turkey adapter
public class DuckTestDrive {
public static void main(String[] args) {
MallardDuck duck = new MallardDuck();
WildTurkey turkey = new WildTurkey();
Duck turkeyAdapter = new TurkeyAdapter(turkey);
System.out.println("The Turkey says...");
turkey.gobble();
turkey.fly();
System.out.println("\nThe Duck says...");
testDuck(duck);
System.out.println("\nThe TurkeyAdapter says...");
testDuck(turkeyAdapter);
}
static void testDuck(Duck duck) {
duck.quack();
duck.fly();
}
}
Real world examples
Adapter pattern in Spring framework
When doing Enterprise Application Development with the Spring Framework, you will be using adapters built into the framework. Spring Integration uses JMS adapters to send and receive JMS messages and JDBC adapters to convert messages to database queries and result sets back to messages. Spring also uses the adapter design pattern to handle load-time-weaving used in Aspect-Oriented Programming (AOP). An adapter is used to inject AspectJ’s aspects to bytecode during class loading done by the servlet container.
Old-world enumerators
https://docs.oracle.com/javase/8/docs/api/java/util/Enumeration.html
Early collection types in Java (Vector, Stack, Hashtable, and a few others) implement a method called elements()
that returns an Enumeration. The Enumeration interface allows you to step through the elements of a collection without knowing the specifics of how they are managed in the collection.
New-world iterators
The newer Collection classes use an Iterator interface that (like Enumeration) allows you to iterate through a set of items in a collection, but also adds the ability to remove items.
Working with Iterators and Enumerators in today’s code
We would like for the new code to use only Iterators. However, you may have to work with legacy code that exposed the Enumeration interface. Here, we can build an adapter.
Collections - Iterators and Enumeration
Conclusion
Some programmers argue that the Adapter pattern is a workaround for a system, which was not well designed keeping into considerations new possibilities. While this is true to some extent, we cannot expect an enterprise application, which will often have a pluggable architecture, to be designed considering all components that might get added in future. In enterprise application development, it is likely that you might need to hook in other libraries, APIs, and “off the shelf” components, and if they are not aligned with the existing system, put the adapter pattern to use. After all, being a core GOF pattern, it is a tested and proven solution used over a long period of time.