All Courses
OOP: DESIGN PATTERNS

Adapter Pattern

Concept Definition

Adapter converts one interface into another interface expected by client code. It wraps an existing class and exposes the method names or return shape that the new code needs. The old class does not have to change.

A real-world analogy is a travel plug adapter. The wall socket and charger do not match directly, so the adapter makes them work together.

Why It Matters

Real projects often contain legacy code, vendor libraries, or old class names that do not match the clean interface you want. Rewriting old code can be risky. Adapter lets new code depend on a stable interface while the adapter translates calls to the old object.

Adapter is especially useful when you want to test new code against an interface without touching the original dependency.

Syntax Block

class Target {
public:
    virtual ~Target() = default;    // common target interface
    virtual std::string request() const = 0;
};

class Adapter : public Target {
    Legacy legacy;                  // wrapped old object
};

Explained Code

Example: Printer Adapter

#include <string> // std::string

class OldPrinter {
public:
    std::string printLegacy() const { return "legacy print"; } // old method name
};

class Printer {
public:
    virtual ~Printer() = default;                 // safe base cleanup
    virtual std::string print() const = 0;        // new expected interface
};

class PrinterAdapter : public Printer {
private:
    OldPrinter oldPrinter;                        // adaptee object

public:
    std::string print() const override {          // target method
        return oldPrinter.printLegacy();          // translate to legacy call
    }
};

Client code calls print() on Printer. It does not need to know that OldPrinter uses printLegacy().

Key Points / Rules

  • Use Adapter when a useful class has the wrong interface.
  • Keep translation logic in the adapter, not scattered across clients.
  • Do not modify stable legacy code if a wrapper is safer.
  • The adapter can own the old object or hold a reference to it.
  • Adapter solves interface mismatch, not bad business logic.

Common Mistakes

  1. Changing every client instead of writing one adapter. This spreads compatibility code everywhere.
  2. Putting new business rules inside the adapter. The adapter should mainly translate calls.
  3. Confusing Adapter with inheritance reuse. Adapter is about interface conversion, not creating an is-a relationship with the old class.
  4. Hiding expensive work. If translation is costly, document it clearly.

Quick Check

  1. Why does PrinterAdapter inherit from Printer?
  2. What is the old class in the example, and what is the new expected interface?

Viva Answer

Adapter lets incompatible interfaces work together. It wraps an existing class and exposes the interface expected by client code.