This is extremely common in embedded systems when integrating legacy drivers, third-party libraries, or hardware modules with different APIs.
- Integrates old and new systems
- Reuses legacy code without modification
C Example
#include <stdio.h>
// Existing driver
void legacySend(char* msg) {
printf("Legacy send: %s\n", msg);
}
// Desired interface
typedef struct {
void (*send)(const char*);
} UART;
// Adapter
void adapterSend(const char* msg) {
legacySend((char*)msg);
}
UART getUARTAdapter() {
UART u;
u.send = adapterSend;
return u;
}
int main() {
UART uart = getUARTAdapter();
uart.send("Hello");
}
C++ Example
#include <iostream>
using namespace std;
class LegacyUART {
public:
void sendData(string msg) {
cout << "Legacy: " << msg << endl;
}
};
class UART {
public:
virtual void send(string msg) = 0;
};
class UARTAdapter : public UART {
LegacyUART legacy;
public:
void send(string msg) override {
legacy.sendData(msg);
}
};
int main() {
UART* uart = new UARTAdapter();
uart->send("Hello");
delete uart;
}