适配器模式(Adapter Pattern)是一种结构型设计模式,它允许不兼容的接口之间能够协同工作。
适配器模式的核心思想是:
接口转换:将一个类的接口转换成客户希望的另一个接口
兼容性:使原本由于接口不兼容而不能一起工作的类可以一起工作
包装:通过包装的方式实现接口转换
目标接口(Target):客户端期望的接口
适配者(Adaptee):需要被适配的现有接口
适配器(Adapter):将适配者接口转换为目标接口的类
下面是一个完整的适配器模式示例,包含详细注释:
#include
#include
#include
#include
// ==================== 目标接口 ====================
// 客户端期望的几何图形接口
class Shape {
public:
virtual void draw(int x1, int y1, int x2, int y2) = 0;
virtual ~Shape() = default;
};
// ==================== 适配者 ====================
// 现有的直线绘制类(不兼容的接口)
class LegacyLine {
public:
void draw(int x1, int y1, int x2, int y2) {
std::cout << "绘制直线: 从(" << x1 << "," << y1
<< ")到(" << x2 << "," << y2 << ")" << std::endl;
}
};
// 现有的矩形绘制类(不兼容的接口)
class LegacyRectangle {
public:
void draw(int x, int y, int w, int h) {
std::cout << "绘制矩形: 左上角(" << x << "," << y
<< "), 宽" << w << ", 高" << h << std::endl;
}
};
// ==================== 适配器 ====================
// 直线适配器(对象适配器)
class LineAdapter : public Shape {
private:
std::unique_ptr adaptee_;
public:
LineAdapter() : adaptee_(std::make_unique()) {}
void draw(int x1, int y1, int x2, int y2) override {
adaptee_->draw(x1, y1, x2, y2);
}
};
// 矩形适配器(对象适配器)
class RectangleAdapter : public Shape {
private:
std::unique_ptr adaptee_;
public:
RectangleAdapter() : adaptee_(std::make_unique()) {}
void draw(int x1, int y1, int x2, int y2) override {
int x = std::min(x1, x2);
int y = std::min(y1, y2);
int width = std::abs(x2 - x1);
int height = std::abs(y2 - y1);
adaptee_->draw(x, y, width, height);
}
};
// ==================== 类适配器(通过多重继承)====================
class ClassAdapter : public Shape, private LegacyRectangle {
public:
void draw(int x1, int y1, int x2, int y2) override {
int x = std::min(x1, x2);
int y = std::min(y1, y2);
int width = std::abs(x2 - x1);
int height = std::abs(y2 - y1);
LegacyRectangle::draw(x, y, width, height);
}
};
// ==================== 客户端代码 ====================
void drawShape(Shape& shape, int x1, int y1, int x2, int y2) {
shape.draw(x1, y1, x2, y2);
}
int main() {
std::cout << "=== 适配器模式演示 ===" << std::endl;
// 使用对象适配器
std::cout << "\n使用对象适配器:" << std::endl;
LineAdapter lineAdapter;
drawShape(lineAdapter, 10, 20, 30, 40);
RectangleAdapter rectAdapter;
drawShape(rectAdapter, 10, 20, 30, 40);
// 使用类适配器
std::cout << "\n使用类适配器:" << std::endl;
ClassAdapter classAdapter;
drawShape(classAdapter, 15, 25, 35, 45);
// 直接使用Legacy类(不兼容)
std::cout << "\n直接使用Legacy类:" << std::endl;
LegacyLine line;
line.draw(5, 5, 25, 25);
LegacyRectangle rect;
rect.draw(5, 5, 20, 20); // 参数含义不同
return 0;
}
兼容性:使不兼容的接口能够协同工作
复用性:可以复用现有的类,无需修改其源代码
灵活性:可以同时适配多个适配者类
开闭原则:引入适配器而不改变现有代码
透明性:对客户端隐藏了适配的细节
当需要使用现有的类,但其接口与你的需求不匹配时
当想要创建一个可复用的类,该类与不相关或不可预见的类协同工作
当需要统一多个现有子类的接口时(适配器可以统一这些接口)
在遗留代码集成、第三方库适配等场景中