Adapter Pattern
The Adapter pattern converts one interface into another clients expect — integrating legacy payment SDK, third-party map API, or old printer driver without rewriting your domain…
Introduction
The Adapter pattern converts one interface into another clients expect — integrating legacy payment SDK, third-party map API, or old printer driver without rewriting your domain code.
In LLD interviews, adapters appear at system boundaries: StripePaymentAdapter implements PaymentGateway. They isolate messy external APIs behind clean internal interfaces (DIP).
Distinguish Adapter (interface conversion) from Facade (simplified subset).
Understanding the topic
Key concepts
- Target interface your domain expects.
- Adaptee existing incompatible class/API.
- Adapter implements Target delegating to Adaptee.
- Object adapter (composition) preferred over class adapter.
- Two-way adapter rare in interviews.
- Anti-corruption layer in DDD is adapter at boundary.
Step-by-step explanation
- Define domain interface (PaymentGateway).
- Identify external API with different method signatures.
- Implement adapter translating calls and errors.
- Map data types both directions carefully.
- Inject adapter as interface in services.
- Test adapter with recorded external responses.
Informative example
Legacy billing SDK adapted to internal PaymentGateway:
public interface PaymentGateway {PaymentResult charge(String userId, Money amount);}public final class LegacyBillingSdk {public int billUser(int userCode, double dollars) {// legacy APIreturn 200;}}public final class LegacyBillingAdapter implements PaymentGateway {private final LegacyBillingSdk sdk;public LegacyBillingAdapter(LegacyBillingSdk sdk) {this.sdk = sdk;}@Overridepublic PaymentResult charge(String userId, Money amount) {int code = Integer.parseInt(userId);int status = sdk.billUser(code, amount.asDouble());return status == 200? new PaymentResult.Success("legacy-" + code): new PaymentResult.Failure("declined");}}
Adapter hides int codes and doubles — domain stays on Money and PaymentResult.
Real-world use
Real-world applications
- Third-party API integration in service design.
- Migrating old module behind new interface.
- Mock external systems in interviews.
Best practices
- Adapter only translates — no business rules.
- Map errors to domain exceptions consistently.
- Keep adapters thin.
- One adapter per external system.
- Document assumptions about external behavior.
Common mistakes
- Business logic inside adapter.
- Leaking adaptee types through Target interface.
- Adapter vs Decorator confusion.
- Giant adapter class handling every endpoint.
Advanced interview questions
Q1BeginnerWhat is Adapter pattern?
Q2BeginnerAdapter vs Facade?
Q3IntermediateObject vs class adapter?
Q4IntermediateWhere place adapters in package structure?
Q5AdvancedAdapt external cab GPS API to internal LocationService.
Summary
Adapter converts incompatible interfaces. Protects domain from external API shapes. Composition-based delegation in Java. Thin translation layer at boundaries. Pairs with DIP and port-adapter architecture.