Adapter Design Pattern Example

Problem Statement

Let’s consider a scenario where we have an existing system that uses a LegacyPrinter class with a method named printDocument() which we want to adapt into a new system that expects a Printer interface with a method named print(). We’ll use the Adapter design pattern to make these two interfaces compatible.

1. Target Interface (Printer)

The interface that the client code expects.

C++




// Target Interface
 
class Printer {
public:
    virtual void print() = 0;
};


2. Adaptee (LegacyPrinter)

The existing class with an incompatible interface.

C++




// Adaptee
 
class LegacyPrinter {
public:
    void printDocument() {
        std::cout << "Legacy Printer is printing a document." << std::endl;
    }
};


3. Adapter (PrinterAdapter)

The class that adapts the LegacyPrinter to the Printer interface.

C++




// Adapter
 
class PrinterAdapter : public Printer {
private:
    LegacyPrinter legacyPrinter;
 
public:
    void print() override {
        legacyPrinter.printDocument();
    }
};


4. Client Code

The code that interacts with the Printer interface.

C++




// Client Code
 
void clientCode(Printer& printer) {
    printer.print();
}


Complete Code for the above example:

C++




// Adapter Design Pattern Example Code
 
#include <iostream>
 
// Target Interface
class Printer {
public:
    virtual void print() = 0;
};
 
// Adaptee
class LegacyPrinter {
public:
    void printDocument() {
        std::cout << "Legacy Printer is printing a document." << std::endl;
    }
};
 
// Adapter
class PrinterAdapter : public Printer {
private:
    LegacyPrinter legacyPrinter;
 
public:
    void print() override {
        legacyPrinter.printDocument();
    }
};
 
// Client Code
void clientCode(Printer& printer) {
    printer.print();
}
 
int main() {
    // Using the Adapter
    PrinterAdapter adapter;
    clientCode(adapter);
 
    return 0;
}


Output

Legacy Printer is printing a document.



Adapter Design Pattern

The Adapter design pattern is a structural pattern that allows the interface of an existing class to be used as another interface. It acts as a bridge between two incompatible interfaces, making them work together. This pattern involves a single class, known as the adapter, which is responsible for joining functionalities of independent or incompatible interfaces.

Let’s understand this concept using a simple example:

Let’s say you have two friends, one who speaks only English and another who speaks only French. You want them to communicate, but there’s a language barrier.

  • You act as an adapter, translating messages between them. Your role allows the English speaker to convey messages to you, and you convert those messages into French for the other person.
  • In this way, despite the language difference, your adaptation enables smooth communication between your friends.
  • This role you play is similar to the Adapter design pattern, bridging the gap between incompatible interfaces.

Important Topics for the Adapter Design Pattern

  • Components of Adapter Design Pattern
  • Adapter Design Pattern Example
  • How Adapter Design Pattern works?
  • Why do we need Adapter Design Pattern?
  • When not to use Adapter Design Pattern?

Similar Reads

Components of Adapter Design Pattern

1. Target Interface...

Adapter Design Pattern Example

Problem Statement...

How Adapter Design Pattern works?

...

Why do we need Adapter Design Pattern?

...

When not to use Adapter Design Pattern?

...