Introduction of Adapter Design Pattern
Adapter Design Pattern : When working on large software systems, you may come across situations where two incompatible interfaces need to work together. Instead of modifying existing code (which may be risky or impossible), you can use the Adapter Pattern to make them compatible.
The Adapter Pattern acts like a bridge between two interfaces. It’s part of the Structural Design Patterns family in C++.
What is the Adapter Design Pattern?
The Adapter Design Pattern allows incompatible interfaces to work together by wrapping an existing class with a new interface.
In simple terms, it’s like using a power plug adapter that lets a U.S. plug fit into a European socket.
Real-life Analogy
Imagine you have an old VGA cable that only works with projectors, but your laptop only has an HDMI port. You can’t plug it in directly. So, you use an HDMI-to-VGA adapter. Now your laptop can talk to the projector!
That’s exactly what the Adapter Pattern does in code.
Components of the Adapter Pattern
- Target – The expected interface (what your code is designed to use)
- Adaptee – The existing class that needs adapting
- Adapter – The class that wraps the Adaptee and makes it compatible with Target
When to Use the Adapter Pattern
- When you want to reuse an existing class, but its interface doesn’t match what you need.
- When you want to decouple code from third-party libraries or legacy code.
- When integrating new features into old systems.
Adapter Pattern in C++ – Code Example
Let’s look at a simple C++ example to understand how it works.
Problem:
We have an existing OldPrinter
class. But our system expects printers to use the NewPrinterInterface
.
Step 1: Define the Target Interface
// Target Interface
class NewPrinterInterface {
public:
virtual void printDocument(const std::string& text) = 0;
virtual ~NewPrinterInterface() {}
};
Step 2: Existing Class (Adaptee)
// Adaptee
class OldPrinter {
public:
void oldPrint(const std::string& text) {
std::cout << "Old Printer Output: " << text << std::endl;
}
};
Step 3: Create the Adapter
// Adapter
class PrinterAdapter : public NewPrinterInterface {
private:
OldPrinter* oldPrinter;
public:
PrinterAdapter(OldPrinter* printer) : oldPrinter(printer) {}
void printDocument(const std::string& text) override {
// Convert the request to match the old interface
oldPrinter->oldPrint(text);
}
};
Step 4: Client Code
int main() {
OldPrinter* legacyPrinter = new OldPrinter();
// Use adapter to make it compatible with the new interface
NewPrinterInterface* printer = new PrinterAdapter(legacyPrinter);
printer->printDocument("Hello, Adapter Pattern!");
delete printer;
delete legacyPrinter;
return 0;
}
Output
Old Printer Output: Hello, Adapter Pattern!
Success! The OldPrinter
works with the new system using the adapter.
Types of Adapters
- Class Adapter (using inheritance): Inherit from both
Target
andAdaptee
(only works in languages with multiple inheritance like C++). - Object Adapter (using composition): Use a reference to
Adaptee
inside theAdapter
. This is more flexible and used in our example above.
Benefits of Adapter Pattern
- Promotes reusability of existing classes
- Helps in code migration and integration
- Makes your design more flexible and maintainable
Drawbacks
- Adds extra layers of code
- May lead to performance overhead
- Can make debugging slightly harder due to indirection
Adapter vs. Other Patterns
Pattern | Purpose |
---|---|
Adapter | Makes incompatible interfaces compatible |
Decorator | Adds behavior to an object dynamically |
Bridge | Decouples abstraction from implementation |
Facade | Provides a simplified interface |
Conclusion
The Adapter Pattern is a powerful tool in a C++ developer’s design toolbox. It allows your code to stay clean, extensible, and compatible with legacy or third-party systems. By wrapping old interfaces with new ones, you avoid rewriting or duplicating code.
Use it wisely when integrating different systems — and you’ll be building robust and scalable software like a pro!
FAQs – Adapter Pattern in C++
Q1. Is Adapter Pattern a structural design pattern?
Yes, it’s part of the Structural design patterns.
Q2. Can we implement Adapter without inheritance?
Yes! You can use composition (object adapter) for a more flexible solution.
Q3. Is Adapter Pattern the same as a Wrapper?
They are similar. A wrapper is a broader term; an adapter is a type of wrapper that converts interfaces.
You can also Visit other tutorials of Embedded Prep
- What is eMMC (Embedded MultiMediaCard) memory ?
- Top 30+ I2C Interview Questions
- Bit Manipulation Interview Questions
- Structure and Union in c
- Little Endian vs. Big Endian: A Complete Guide
- Merge sort algorithm
Special thanks to @mr-raj for contributing to this article on Embedded Prep
Leave a Reply