设计模式十四:适配器模式(Adapter Pattern)
适配器模式(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
)实现的。