Structural PatternsAdapter PatternHard⏱️ ~3 min

Adapter Pattern: Common Interview Questions

Interviewers test your understanding of Adapter Pattern through design scenarios, trade-off discussions, and machine coding challenges. Here are the most common question patterns and how to approach them.

Question 1: Design a Logger System with Multiple Backends

Problem: Your application needs to log messages to different backends (Console, File, CloudWatch, Splunk). Each backend has a different API. Design a unified logging interface.

Approach:

First, define a target interface Logger with log(level, message). Second, create adapters for each backend: ConsoleLoggerAdapter, FileLoggerAdapter, CloudWatchAdapter. Third, each adapter wraps the backend-specific API and translates log() calls to the appropriate backend method. Fourth, use a Factory Pattern to instantiate the correct adapter based on configuration.

interface Logger:
  + log(level: LogLevel, message: String): void

class CloudWatchAdapter implements Logger:
  - cloudWatch: CloudWatchAPI
  + log(level, message):
    severity = mapLevelToSeverity(level)
    cloudWatch.putLogEvent(severity, message, timestamp)

class FileLoggerAdapter implements Logger:
  - fileWriter: FileWriter
  + log(level, message):
    formatted = formatMessage(level, message)
    fileWriter.write(formatted)
Interview Tip: Mention that you would handle exceptions differently for each backend. Console logging failures should not crash the app, but CloudWatch failures might need retry logic. Ask the interviewer about error handling requirements.

Question 2: Adapter vs Bridge Pattern

Problem: Explain when you would use Adapter Pattern versus Bridge Pattern with concrete examples.

Answer Structure:

Intent Difference: Adapter is applied retroactively to make incompatible interfaces work together. Bridge is designed upfront to decouple abstraction from implementation so both can vary independently.

Adapter Example: You integrate a third-party SMS service (Twilio) that has sendSMS(to, from, body) into your notification system that expects send(recipient, message). You create TwilioAdapter to translate between the two interfaces. You did not design Twilio's API, you are adapting it.

Bridge Example: You design a shape rendering system where shapes (Circle, Square) can be rendered on different platforms (Windows, Linux). You create a Renderer interface and pass it to shape constructors. Shapes delegate rendering to the injected renderer. Both shape hierarchy and renderer hierarchy can evolve independently. You designed this from the beginning.

Question 3: Machine Coding - Parking Lot with Multiple Payment Processors

Problem: Design a parking lot system where users can pay via Cash, Card, or Mobile Wallet. Each payment method has different processing logic. Implement using Adapter Pattern.

Key Design Decisions:

First, define PaymentMethod interface with processPayment(amount): PaymentResult. Second, create adapters for each method: CashPaymentAdapter (no external API, just records transaction), CardPaymentAdapter (adapts card processor API), WalletAdapter (adapts PayTM/Google Pay API). Third, in ParkingTicket class, accept PaymentMethod interface and call processPayment() without knowing the concrete implementation.

interface PaymentMethod:
  + processPayment(amount: Money): PaymentResult

class CardPaymentAdapter implements PaymentMethod:
  - cardProcessor: CardProcessorAPI
  - card: CreditCard
  + processPayment(amount):
    if not validateCard(card):
      return PaymentResult.FAILED
    response = cardProcessor.charge(card.number, amount.cents)
    return convertResponse(response)

class ParkingTicket:
  - paymentMethod: PaymentMethod
  + checkout():
    amount = calculateFee()
    result = paymentMethod.processPayment(amount)
    if result.isSuccess():
      markAsPaid()

Follow-up Questions to Expect:

First, how do you handle payment failures and retries? (Add retry logic in adapters or create a RetryablePaymentAdapter decorator). Second, how do you handle refunds? (Add refund() to PaymentMethod interface, implement in each adapter). Third, how do you handle partial payments? (Modify interface to accept paid amount and return remaining balance, but clarify if this is a requirement before implementing).

Question 4: Two-Way Adapter

Problem: Can an adapter work both ways? Explain with an example.

Answer: Yes, a Two-Way Adapter (also called Bidirectional Adapter) implements both interfaces and delegates calls in both directions. This is useful when two subsystems need to collaborate but have incompatible interfaces.

Example: In a library management system, you have a legacy BookInventory system and a new CatalogService. The legacy system uses findByISBN() while the new system uses searchByIdentifier(). A two-way adapter implements both interfaces and translates calls bidirectionally. However, this is rare in practice because it tightly couples two systems. Usually, you pick one interface as the target and adapt everything to it.

Interview Tip: When discussing two-way adapters, immediately mention the tight coupling risk and suggest alternatives like creating a new unified interface that both systems adapt to instead of adapting to each other.
💡 Key Takeaways
Logger system with multiple backends demonstrates practical adapter usage
Adapter is retroactive; Bridge is designed upfront for independent variation
In machine coding, start with interface definition before implementing adapters
Handle edge cases: payment failures, retries, refunds in adapter implementations
Two-way adapters are possible but create tight coupling; prefer unified interface
📌 Examples
1Logger adapters for Console, File, CloudWatch backends
2Payment method adapters in parking lot system
3Card processor adapter with validation and error handling
← Back to Adapter Pattern Overview
Adapter Pattern: Common Interview Questions | Adapter Pattern - System Overflow