Java Adapter Pattern
In this page:
What is the Adapter Pattern?
The Adapter pattern converts the interface of an existing class into another interface that client code expects, letting classes with otherwise incompatible interfaces work together without modifying either one.
Example: What is the Adapter Pattern?
public class Main {
interface Target { void request(); }
static class Adaptee { void specificRequest() { System.out.println("Adaptee's own method"); } }
static class Adapter implements Target {
Adaptee adaptee = new Adaptee();
public void request() { adaptee.specificRequest(); } // translates one interface to another
}
public static void main(String[] args) {
Target t = new Adapter();
t.request();
}
}
Login to try C/C++/Java/PHP code in the editor
Class Adapter vs Object Adapter
A class adapter uses inheritance to extend the adaptee directly, while an object adapter uses composition, holding a reference to the adaptee instance -- Java's single inheritance limits favor the object adapter approach in most cases.
Example: Class Adapter vs Object Adapter
public class Main {
static class Adaptee { void specific() { System.out.println("specific()"); } }
interface Target { void request(); }
static class ObjectAdapter implements Target { // composition -- holds a reference
Adaptee adaptee = new Adaptee();
public void request() { adaptee.specific(); }
}
public static void main(String[] args) {
new ObjectAdapter().request(); // Java favors this over class-adapter inheritance
}
}
Login to try C/C++/Java/PHP code in the editor
Adapting a Legacy Interface
Adapters are especially common when integrating with legacy code or a third-party library whose API doesn't match what the rest of an application expects, isolating that mismatch behind a single translation class.
Example: Adapting a Legacy Interface
public class Main {
static class LegacyPrinter { void oldPrint(String s) { System.out.println("Legacy: " + s); } }
interface ModernPrinter { void print(String s); }
static class PrinterAdapter implements ModernPrinter {
LegacyPrinter legacy = new LegacyPrinter();
public void print(String s) { legacy.oldPrint(s); } // isolates the mismatch here
}
public static void main(String[] args) {
ModernPrinter p = new PrinterAdapter();
p.print("Hello");
}
}
Login to try C/C++/Java/PHP code in the editor
Adapting Data Formats
Beyond just renaming methods, an adapter can also convert data between formats or units entirely, such as translating XML to JSON or Fahrenheit to Celsius, while presenting a clean target interface to callers.
Example: Adapting Data Formats
public class Main {
interface TemperatureReader { double celsius(); }
static class FahrenheitSensor { double readFahrenheit() { return 98.6; } }
static class TemperatureAdapter implements TemperatureReader {
FahrenheitSensor sensor = new FahrenheitSensor();
public double celsius() { return (sensor.readFahrenheit() - 32) * 5 / 9; } // converts units, not just names
}
public static void main(String[] args) {
System.out.println(new TemperatureAdapter().celsius());
}
}
Login to try C/C++/Java/PHP code in the editor
Adapter vs Facade
Adapter and Facade both wrap other code, but Adapter exists to make one specific incompatible interface fit an expected one, while Facade exists to simplify access to an entire complex subsystem behind a single simplified interface.
Example: Adapter vs Facade
public class Main {
interface Target { void request(); } // Adapter: makes ONE incompatible interface fit
static class SubsystemA { void a() { System.out.println("A"); } }
static class SubsystemB { void b() { System.out.println("B"); } }
static class Facade { // Facade: simplifies access to a WHOLE subsystem
void doEverything() { new SubsystemA().a(); new SubsystemB().b(); }
}
public static void main(String[] args) {
new Facade().doEverything();
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first:
- Java Design Patterns Introduction
- Java Singleton Pattern
- Java Factory Pattern
- Java Observer Pattern
- Java Builder Pattern
- Java MVC Architecture
- Java Adapter Pattern
- Java Decorator Pattern
- Java Strategy Pattern
- Java Command Pattern
- Java Facade Pattern
- Java Proxy Pattern
- Java Template Method Pattern
- Java Repository Pattern