Convert the interface of a class into another interface clients expect. Adapter (or Wrapper) lets classes work together that couldn’t otherwise because of incompatible interfaces. Adapter pattern’s motivation is that we can reuse existing software if we can modify the interface.
Example:
#include <iostream>
// Desired interface (Target)
class Rectangle
{
public:
virtual void draw() = 0;
};
// Legacy component (Adaptee)
class LegacyRectangle
{
public:
LegacyRectangle(int x1, int y1, int x2, int y2) {
x1_ = x1;
y1_ = y1;
x2_ = x2;
y2_ = y2;
std::cout << "LegacyRectangle(x1,y1,x2,y2)\\n";
}
void oldDraw() {
std::cout << "LegacyRectangle: oldDraw(). \\n";
}
private:
int x1_;
int y1_;
int x2_;
int y2_;
};
// Adapter wrapper
class RectangleAdapter: public Rectangle, private LegacyRectangle
{
public:
RectangleAdapter(int x, int y, int w, int h):
LegacyRectangle(x, y, x + w, y + h) {
std::cout << "RectangleAdapter(x,y,x+w,x+h)\\n";
}
void draw() {
std::cout << "RectangleAdapter: draw().\\n";
oldDraw();
}
};
int main()
{
int x = 20, y = 50, w = 300, h = 200;
Rectangle *r = new RectangleAdapter(x,y,w,h);
r->draw();
}
//Output:
//LegacyRectangle(x1,y1,x2,y2)
//RectangleAdapter(x,y,x+w,x+h)
Summary of the code:
Rectangle
Rectangle
class. This is what the client invokes method on.Rectangle *r = new RectangleAdapter(x,y,w,h);
r->draw();
class RectangleAdapter: public Rectangle, private LegacyRectangle {
...
}
RectangleAdapter
lets the LegacyRectangle
responds to request (draw()
on a Rectangle
) by inheriting BOTH classes.LegacyRectangle
class does not have the same methods (draw()
) as Rectangle
, but the Adapter(RectangleAdapter)
can take the Rectangle
method calls and turn around and invoke method on the LegacyRectangle
, oldDraw()
.class RectangleAdapter: public Rectangle, private LegacyRectangle {
public:
RectangleAdapter(int x, int y, int w, int h):
LegacyRectangle(x, y, x + w, y + h) {
std::cout << "RectangleAdapter(x,y,x+w,x+h)\\n";
}
void draw() {
std::cout << "RectangleAdapter: draw().\\n";
oldDraw();
}
};
Adapter design pattern translates the interface for one class into a compatible but different interface. So, this is similar to the proxy pattern in that it’s a single-component wrapper. But the interface for the adapter class and the original class may be different.
As we’ve seen in the example above, this adapter pattern is useful to expose a different interface for an existing API to allow it to work with other code. Also, by using adapter pattern, we can take heterogeneous interfaces, and transform them to provide consistent API.
Bridge pattern has a structure similar to an object adapter, but Bridge has a different intent: It is meant to separate an interface from its implementation so that they can be varied easily and independently. An adapter is meant to change the interface of an existing object.