#include <iostream>
// ------------------- Target Interface -------------------
class Shape {
public:
virtual void draw() const = 0; // Interface expected by client
virtual ~Shape() = default;
};
// ------------------- Adaptee (Legacy Interface) -------------------
// Existing rectangle drawing class with incompatible interface
class LegacyRectangle {
public:
// Draw rectangle using top-left coordinates (x, y) and dimensions (w, h)
void drawRectangle(int x, int y, int w, int h) const {
std::cout << "LegacyRectangle: drawing rectangle at ("
<< x << ", " << y << ") with width "
<< w << " and height " << h << std::endl;
}
};
// ------------------- Adapter -------------------
// Adapt LegacyRectangle to Shape interface through composition (object adapter)
class RectangleAdapter : public Shape {
private:
LegacyRectangle legacy_; // Adapted object
int x_, y_, w_, h_; // Rectangle parameters
public:
RectangleAdapter(int x, int y, int w, int h)
: x_(x), y_(y), w_(w), h_(h) {}
// Implement target interface, internally call adaptee's method
void draw() const override {
std::cout << "RectangleAdapter: adapting call to LegacyRectangle..." << std::endl;
legacy_.drawRectangle(x_, y_, w_, h_);
}
};
// ------------------- Another normal Shape implementation -------------------
class Circle : public Shape {
public:
void draw() const override {
std::cout << "Circle: drawing a circle" << std::endl;
}
};
// ------------------- Client -------------------
int main() {
// Uniformly operate different shapes through base class pointers
Shape* shapes[2];
shapes[0] = new Circle();
shapes[1] = new RectangleAdapter(10, 20, 100, 50); // Use adapter
for (int i = 0; i < 2; ++i) {
shapes[i]->draw(); // Client only depends on Shape interface
}
// Release resources
delete shapes[0];
delete shapes[1];
return 0;
}