适配器模式(Adapter Pattern)是一种结构型设计模式,用于将一个类的接口转换成客户端期望的另一个接口,使原本不兼容的类可以一起工作。
适配器模式的类型
类适配器(通过多重继承实现)
对象适配器(通过组合实现,更常用)
示例代码
1. 对象适配器示例(推荐方式)
#include <iostream>
// 目标接口(客户端期望的接口)
class Target {
public:
virtual ~Target() = default;
virtual void request() const {
std::cout << "Target: 标准请求\n";
}
};
// 需要适配的类(不兼容的接口)
class Adaptee {
public:
void specificRequest() const {
std::cout << "Adaptee: 特殊请求\n";
}
};
// 适配器类(将Adaptee接口转换为Target接口)
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* a) : adaptee(a) {}
void request() const override {
std::cout << "Adapter: 转换请求\n";
adaptee->specificRequest();
}
};
int main() {
Adaptee* adaptee = new Adaptee();
Target* target = new Adapter(adaptee);
target->request(); // 客户端调用统一的接口
delete target;
delete adaptee;
return 0;
}
2. 类适配器示例(需要多重继承)
#include <iostream>
// 目标接口
class Target {
public:
virtual ~Target() = default;
virtual void request() const {
std::cout << "Target: 标准请求\n";
}
};
// 需要适配的类
class Adaptee {
public:
void specificRequest() const {
std::cout << "Adaptee: 特殊请求\n";
}
};
// 类适配器(通过多重继承)
class Adapter : public Target, private Adaptee {
public:
void request() const override {
std::cout << "Adapter: 转换请求\n";
specificRequest(); // 调用Adaptee的方法
}
};
int main() {
Target* target = new Adapter();
target->request();
delete target;
return 0;
}
UML结构
要点总结
1、Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
2、GoF 23 定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
3、Adapter模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。
适配器模式的应用场景
需要使用现有类,但其接口与你的代码不兼容时
想复用一些现有的子类,但这些子类缺少一些公共功能
需要统一多个不同类的接口
优点
单一职责原则:可以将接口转换代码与业务逻辑分离
开闭原则:可以在不修改现有代码的情况下引入新的适配器
缺点
代码整体复杂度增加:需要新增一系列接口和类
适配器模式在C++标准库中也有应用,例如stack
和queue
就是通过适配其他容器(如deque
)实现的。