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
- Changing every client instead of writing one adapter. This spreads compatibility code everywhere.
- Putting new business rules inside the adapter. The adapter should mainly translate calls.
- Confusing Adapter with inheritance reuse. Adapter is about interface conversion, not creating an
is-arelationship with the old class. - Hiding expensive work. If translation is costly, document it clearly.
Quick Check
- Why does
PrinterAdapterinherit fromPrinter? - 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.