Adapter
Make two incompatible interfaces work together by wrapping one in an Adapter that translates calls β like a power plug converter for your code.
Intent & Description
π― Intent
Let an existing class work in a context that expects a different interface β without modifying either class.
π Context
You’re integrating a third-party library, legacy system, or SDK that has a useful implementation but a completely different interface from what your codebase expects. You can’t modify the external class and don’t want to rewrite the consumers.
π‘ Solution
Create an Adapter class that implements the interface your code expects and internally holds a reference to the adaptee (the incompatible class). The Adapter translates method calls: adapter.newMethod() maps to adaptee.oldMethod(). Consumers never know they’re talking to an adapter.
Real-world Use Case
Source
π TL;DR
Wraps an incompatible class in a translator. Client calls the interface it expects; Adapter converts to what the adaptee understands. Essential for integrating third-party code cleanly.
Advantages
- Integration code stays separate from business logic β clean Single Responsibility.
- Add new adapters without touching existing client code or the adaptee.
Disadvantages
- Adds a class and indirection layer β minor overhead for simple integrations.
// Old interface
class OldCalculator {
operations(t1, t2, operation) {
switch (operation) {
case 'add': return t1 + t2;
case 'sub': return t1 - t2;
default: return NaN;
}
}
}
// New interface
class NewCalculator {
add(t1, t2) { return t1 + t2; }
sub(t1, t2) { return t1 - t2; }
}
// Adapter
class CalcAdapter {
constructor() {
this.cal = new NewCalculator();
}
operations(t1, t2, operation) {
switch (operation) {
case 'add': return this.cal.add(t1, t2);
case 'sub': return this.cal.sub(t1, t2);
default: return NaN;
}
}
}