C++ 适配器模式
外观
C++适配器模式[编辑 | 编辑源代码]
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许不兼容的接口之间进行协作。该模式通过将一个类的接口转换成客户端期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以协同工作。
介绍[编辑 | 编辑源代码]
适配器模式在C++中常用于以下场景:
- 将旧代码集成到新系统中
- 使用第三方库时接口不匹配
- 为不同的子系统提供统一的接口
适配器模式有两种主要实现方式: 1. 类适配器 - 通过多重继承实现 2. 对象适配器 - 通过组合实现
类适配器[编辑 | 编辑源代码]
类适配器使用多重继承来适配接口。它继承目标接口和被适配者类。
// 目标接口
class Target {
public:
virtual ~Target() = default;
virtual void request() = 0;
};
// 被适配者
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee's specific request" << std::endl;
}
};
// 类适配器
class ClassAdapter : public Target, private Adaptee {
public:
void request() override {
specificRequest(); // 调用被适配者的方法
}
};
// 使用示例
int main() {
Target* target = new ClassAdapter();
target->request(); // 输出: Adaptee's specific request
delete target;
return 0;
}
对象适配器[编辑 | 编辑源代码]
对象适配器使用组合而非继承,这种方式更灵活,是更常用的实现方式。
// 目标接口
class Target {
public:
virtual ~Target() = default;
virtual void request() = 0;
};
// 被适配者
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee's specific request" << std::endl;
}
};
// 对象适配器
class ObjectAdapter : public Target {
private:
Adaptee* adaptee;
public:
ObjectAdapter(Adaptee* a) : adaptee(a) {}
void request() override {
adaptee->specificRequest(); // 委托给被适配者
}
};
// 使用示例
int main() {
Adaptee* adaptee = new Adaptee();
Target* target = new ObjectAdapter(adaptee);
target->request(); // 输出: Adaptee's specific request
delete target;
delete adaptee;
return 0;
}
实际应用案例[编辑 | 编辑源代码]
案例:图形渲染接口适配
假设我们有一个现代图形库(ModernRenderer)和一个遗留图形库(LegacyRenderer),它们的接口不兼容:
// 现代图形接口
class ModernRenderer {
public:
virtual void render(float x, float y, float width, float height) = 0;
};
// 遗留图形接口
class LegacyRenderer {
public:
void draw(int x1, int y1, int x2, int y2) {
std::cout << "Legacy renderer drawing from (" << x1 << "," << y1
<< ") to (" << x2 << "," << y2 << ")" << std::endl;
}
};
// 适配器
class RendererAdapter : public ModernRenderer {
private:
LegacyRenderer* legacyRenderer;
public:
RendererAdapter(LegacyRenderer* renderer) : legacyRenderer(renderer) {}
void render(float x, float y, float width, float height) override {
// 将现代接口的参数转换为遗留接口的参数
int x1 = static_cast<int>(x);
int y1 = static_cast<int>(y);
int x2 = static_cast<int>(x + width);
int y2 = static_cast<int>(y + height);
legacyRenderer->draw(x1, y1, x2, y2);
}
};
// 使用示例
int main() {
LegacyRenderer legacyRenderer;
ModernRenderer* renderer = new RendererAdapter(&legacyRenderer);
renderer->render(10.5f, 20.5f, 100.0f, 200.0f);
// 输出: Legacy renderer drawing from (10,20) to (110,220)
delete renderer;
return 0;
}
类图[编辑 | 编辑源代码]
以下是适配器模式的类图表示:
优缺点[编辑 | 编辑源代码]
优点:
- 使不兼容的接口能够协同工作
- 遵循开闭原则(对扩展开放,对修改关闭)
- 提高代码复用性
缺点:
- 增加系统复杂性
- 在某些情况下可能降低性能(由于额外的间接调用)
与其他模式的关系[编辑 | 编辑源代码]
总结[编辑 | 编辑源代码]
适配器模式是解决接口不兼容问题的有效工具。在C++中,对象适配器(使用组合)通常比类适配器(使用多重继承)更受欢迎,因为它更灵活且避免了多重继承的复杂性。当需要集成旧代码或第三方库时,适配器模式特别有用。